0

オブジェクトには、コールバック関数の配列と、この関数が設定されているイベントの名前を取得するメンバー関数があります。

...
setHandlesByList: function (list) {
    for (var i in list) {
        var self = this;
        $(document).on(list[i].name, function (e) {
            list[i].callBack.call(self,e)
        });
    };
},
...

子オブジェクトのどこかで、親オブジェクトのこの関数を呼び出しています。

...
initClass: function () {
    this.setHandlesByList([
     { name: 'configChecked', callBack: onConfigChecked },
     { name: 'configExpired', callBack: onConfigExpired },
    ]);
},
onConfigChecked: function() {
    // some code
},
onConfigExpired: function() {
    // some code
},
....

しかし、何かがうまくいかない - すべてのイベントで、ハンドラーは最後に設定されたコールバック関数です...

4

2 に答える 2

3

次のことを試してください。

setHandlesByList: function (list) {
    for ( var i = 0; i < list.length; i++ ) {
        addCallback(list[i].name, list[i].callback);
    }
    function addCallback(on, name, callback) {
        $(document).on(name, function(e) { callback.call(on, e); });
    }
},

i最終的に の値はi、コールバックが評価されるときの最後の値になるため、スコープに問題があります。

を使用できることにも注意してくださいlist.forEach

于 2013-10-16T21:31:36.067 に答える
2

このコードで作成する各イベント ハンドラー関数:

setHandlesByList: function (list) {
    for (var i in list) {
    var self = this;
    $(document).on(list[i].name, function (e) {
        list[i].callBack.call(self,e)
        });
    };
},

...関数が作成された時点でのコピーではなく、およびへの永続的な参照があります。最後に列挙されたプロパティになるため、すべてのハンドラーは同じリスト エントリを参照することになります。listii

代わりに、コールバックを作成するビルダー関数を作成します(申し訳ありませんが、使用しているインデント スタイルを再作成することはできません。かなり標準的なスタイルを使用しただけです)

setHandlesByList: function (list) {
    var self = this;

    for (var i in list) {
        $(document).on(list[i].name, buildHandler(list[i]));
    };

    function buildHandler(entry) {
        return function (e) {
            entry.callBack.call(self,e)
        };
    }
},

これで、作成された関数は、と ではなく、呼び出しのentry引数である を閉じます。(引数) は変わらないので、ハンドラは動作します。buildHandlerlistientry

var self = this;また、反復ごとに変化せず、ループ内にビジネスがなかったので、ループの外に移動したことにも注意してください。


補足:関数が配列を受け取ると言いました。そうである場合、for-in(セーフガードなしで) その配列内のエントリをループする正しい方法ではありません。詳細:神話と現実for..in

于 2013-10-16T21:30:22.233 に答える