3

新しいビューのプッシュをトリガーするボタンがあるとします。何度もクリックすると、十分に速く、同じビューが 2 回プッシュされることに気付きました。

ライブサンプルがあるこのページの公式ドキュメントを使用して、この動作を模倣できます: http://docs.sencha.com/touch/2-0/#!/guide/navigation_view

明確な問題は、単にそれを防ぐ方法ですか?

4

10 に答える 10

8

もう 1 つの方法は、アクティブなビューが何であるかを確認し、プッシュしようとしているビューと同じでない場合にのみプッシュすることです。私はこれをテストしましたが、動作します。

例えば

if (this.getNavigationView().getActiveItem().xtype != "someView") {
    this.getNavigationView().push({ xtype: "someView" });
}
于 2013-02-11T07:07:26.393 に答える
6

jayteejee の回答を拡張して、次のようにカスタム ナビゲーション ビューで push メソッドをオーバーライドしました。

Ext.define('BT.navigation.View', {
   extend: 'Ext.navigation.View',
   xtype: 'btnavigationview',

   push: function (view) {
      if(this.getActiveItem().xtype != view.xtype)
         this.callParent(arguments);
      else
         console.warn("Prevented pushing a potentially duplicate view of xtype: " + view.xtype);
   }
});

仮定が十分に安全かどうかは完全にはわかりませんxtypeが、現在のアプリで、あるビューが同じタイプの別のビューをナビゲーション スタックにプッシュする必要がある状況は考えられません。だから、解決策は私にとってはうまくいきます、そしてそれはかなりきれいです。push警告は、後で頭痛がするのを防ぐためにあります。なぜうまくいかないのかを解決しようとして髪を引っ張る可能性があります。

于 2013-03-15T13:01:41.933 に答える
4

マスキングにより、ダブルタップの問題を防ぐことができます。

私のコードでは、ナビゲーション コンテナーのマスク/マスク解除に 2 つの関数を使用しています。

/**
 * Mask container with rolling wheel. Usually need if Ajax-request is sent to the server and app waiting for response
 * Best practice is masking the current navigator container, to prevent blocking whole app. Method warns if no container
     * is defined. In some cases warning could be suppress with parameter
     *
     * @param container
     * @param {boolean} [suppressWarning]
     */
    startLoading: function(container, suppressWarning) {
        var loadingComponent = container;

        if (!loadingComponent) {
            // <debug>
            if (!suppressWarning) {
                console.warn('Please define navigator container for non-blocking operation, or define suppressWarning parameter');
            }
            // </debug>
            loadingComponent = Ext.Viewport;
        }

//      var lastMaskedContainer = container;
        this.lastMaskedContainer = container;

        loadingComponent.setMasked({
            xtype: 'loadmask',
            message: 'Loading...'
        });

/*
        Ext.defer(function() {
            lastMaskedContainer.setMasked(false);
        }, Pipedrive.app.maskingTimeout * 1000)
*/
    },

    /**
     *
     * @param {Ext.Container} container
     * @param {boolean} [suppressWarning]
     */
    stopLoading: function(container, suppressWarning) {
        var loadingComponent = container;

        if (!loadingComponent) {
            // <debug>
            if (!suppressWarning) {
                console.warn('Please define either navigator container for non-blocking operation, or define suppressWarning parameter');
            }
            // </debug>
            loadingComponent = Ext.Viewport;
        }

        var alreadyMasked = loadingComponent.getMasked();

        var lastMaskedContainer = this.lastMaskedContainer;
        if (!alreadyMasked && !suppressWarning) {
            // <debug>
            if (lastMaskedContainer != container) {
                console.warn('Found Start/Stop Loading inconsistency. Please revise code'
                    + (container ? '. Container: ' + container.getId() : 'Ext.Viewport')
                    + (lastMaskedContainer ? ', last masked container: ' + lastMaskedContainer.getId() : '')
                );
            }
            // </debug>
            loadingComponent = Ext.Viewport;
        }
        loadingComponent.setMasked(false);
    }

タップハンドラーよりも:

onDealDetailsTap: function(ct) {
    console.log('onDealDetailsTap', ct);
    var form = ct.getReferenceForm(),
        navigatorContainer = this.getNavigatorContainer(form),
        model = form.getRecord();

    UiHelper.startLoading(navigatorContainer);
    Ext.Viewport.fireEvent('detailfields', {
        title: model.get('title'),
        id: model.get('id'),
        store: 'DealFields',
        navigatorContainer: navigatorContainer
    })
},

ローディングマスクをクリーンアップするには:

control : {
    activitiesContainer: {
        push: 'onPushActivitiesContainer'
    },




onPushActivitiesContainer: function(ct) {
    //console.log('onPushActivitiesContainer', ct);
    UiHelper.stopLoading(ct);
},

特に、長時間の ajax リクエストを待つのはクールです....

乾杯、オレグ

于 2012-07-17T22:30:42.450 に答える
2

ボタンがタップされたときにイベントを一時停止し、ビューが押されたときにイベントを再開するだけです

button.suspendEvents();
...
button.resumeEvents();

他の方法はないと思います。開発者またはユーザーとして、ボタンを 2 回タップすると、イベント ハンドラーが 2 回呼び出されることが予想されます。

お役に立てれば

于 2012-07-17T22:26:32.207 に答える
2

コンテナ全体をマスクしてからマスクを解除するだけです。コントローラーとタップセットにボタンが存在するコンテナーまたはパネルの参照を作成します。

ref.setMasked(true)

新しいビューがプッシュされた後、単純にマスクを解除します

ref.setMasked(false)
于 2012-09-06T12:46:19.183 に答える
0

これを確認するためのメソッドを作成しました:

    ENSURE_NO_DOUBLE_TAP : function(classNameToPush) {
        if (Ext.getClassName(Ext.getCmp('MyViewport').getActiveItem()) == classNameToPush) {
            return false;
        }

        return true;
    }

次に、ダブルタップされる可能性のあるものが処理される前に、アプリから:

        if (!ENSURE_NO_DOUBLE_TAP('MyApp.view.View')) {
            return;
        }
于 2013-07-01T18:38:41.343 に答える
0

もう 1 つの方法は、次のように、リスト項目が 1 回タップされるとパラメーターを反転することです。

{
   onListItemTap: function () {
      if (!this.tapped) {
         this.tapped = true;
         ...
      }
   }
}

もちろん、これは、ユーザーが別の画面に移動するとすぐにリスト ビューを破棄している場合にのみ機能します。

于 2013-06-29T21:18:50.060 に答える
0

リスナーを使用してボタンのタップイベントをリッスンしている場合、私の解決策は次のとおりです。

listeners : {   
     release : function(){                                  
          if(this.getDisabled())return false;
          this.setDisabled(true);
          this.fireEvent('tap');
     },
     tap : function() {
         //do what you want
     }
 }
于 2013-09-26T09:08:53.327 に答える
0

「itemsingletap」イベントを使用するだけです。

ダブルタップもサポートしたい場合は、「itemdoubletap」の 2 つ目のリスナーを作成し、同じ関数を呼び出すと、両方のリスナーが連携して正常に動作します。

于 2015-01-07T10:28:03.023 に答える