0

このページclassに表示されているバインディングを変更しようとしています:

ko.bindingHandlers['class'] = {
    'update': function(element, valueAccessor) {
        if (element['__ko__previousClassValue__']) {
            ko.utils.toggleDomNodeCssClass(element, element['__ko__previousClassValue__'], false);
        }
        var value = ko.utils.unwrapObservable(valueAccessor());
        ko.utils.toggleDomNodeCssClass(element, value, true);
        element['__ko__previousClassValue__'] = value;
    }
};

だから、現在、私のものはこのようなものです:

ko.bindingHandlers.cssClass = {
    update: function (element, valueAccessor) {
        var cssClass = ko.utils.unwrapObservable(valueAccessor()),
            prevCssClass = element['__ko__previousClassValue__'];

        console.log("Previous:", prevCssClass);
        console.log("Current:", cssClass);

        if (Object.prototype.toString.call(prevCssClass) === '[object Array]') {
            ko.utils.arrayForEach(prevCssClass, function (classAccessor) {
                var value = ko.utils.unwrapObservable(classAccessor);
                ko.utils.toggleDomNodeCssClass(element, value, false);
            });
        } else if (prevCssClass) {
            ko.utils.toggleDomNodeCssClass(element, prevCssClass, false);
        }

        if (Object.prototype.toString.call(cssClass) === '[object Array]') {
            ko.utils.arrayForEach(cssClass, function (classAccessor) {
                var value = ko.utils.unwrapObservable(classAccessor);
                ko.utils.toggleDomNodeCssClass(element, value, true);
            });
        } else if (cssClass) {
            ko.utils.toggleDomNodeCssClass(element, cssClass, true);
        }

        element['__ko__previousClassValue__'] = cssClass;
    }
};

遊べるフィドルを作りました。私の質問は、最初に[変更]をクリックすると、これは魅力のように機能しますが、その後はいつでも、観測可能な配列に対してprevCssClass正しくありません(単一はうまく機能します)...それは実際には前の値であるべきではないことを反映しています。なんで?なぜこれが起こっているのか理解できません、すべてが私には大丈夫のようです。multiplecssClass

悪いコンソール出力は次のとおりです。

Previous: undefined
Current: ["blue","small"]

Previous: ["blue"]
Current: ["blue"]

Previous: ["blue","big"]
Current: ["blue","big"]

正しい出力は次のようになります。

Previous: undefined
Current: ["blue","small"]

Previous: ["blue","small"]
Current: ["blue"]

Previous: ["blue"]
Current: ["blue","big"]

Chromeでテストしています。

アップデート:

答えは以下の通りです。興味があれば、この新しいバインディングの要点はここにあります(すべてクリーンアップされています):

https://gist.github.com/kamranayub/5224521

4

1 に答える 1

1

これは私がどこかで見つけたちょっとしたjavascriptのトリックです...多分jQueryのソース、私は思い出せません。

重要なのは、アレイのコピーを作成することです。基本的にnull配列を.concat()追加すると、Javascriptは既存の配列のコピーを作成します。

if (Object.prototype.toString.call(prevCssClass) === '[object Array]') {
    prevCssClass = prevCssClass.concat();

これにより、現在のアレイの履歴コピーを保存できます。また、元のオブジェクトを変更しても、「クローン」配列には影響しません。

于 2013-03-22T20:19:06.857 に答える