3

私は Knockout.js にかなり慣れていないので、何かが足りないだけかもしれません。「選択された」状態が配列内の項目のサブ値を反映するボタンとして機能する div のセットを作成しようとしています。

このフィドルを参照してください: http://jsfiddle.net/bleiddyn/RepnY/

抜粋:

    $('.tag-cell').click(function() {
        var ele = event.srcElement.textContent;
        var match = ko.utils.arrayFirst(self.Tags(), function(item) {
            if (ele === item.title) {
                item.chosen = !item.chosen;
                return true;
            }
            return false;
        });

        match.chosen = true;
        self.Tags.valueHasMutated();
    });

div の初期表示は正しいです。クリックイベントでオブザーバブル配列内の値を問題なく変更できるようです。ただし、表示される div はこれに応じて css クラスを変更しません。

配列内の項目であるオブジェクトの子は、それ自体では観察できないことに気付きました。ただし、 valueHasMutated() への呼び出しで問題が発生することはありませんか? これは、動作を実現するための最も洗練された方法ではない可能性があります。

JavaScript を学んでいる人を助けたい人はいますか?

4

2 に答える 2

2

バインドされたプロパティを更新するには、問題のプロパティを監視可能にする必要があります。clickまた、ここではイベントを処理するためにjQueryは必要ありません。eventバインディングを使用して、次のことを実行できます。

function item(options) {
    var self = this;
    this.title = ko.observable(options.title);
    this.level = ko.observable(options.level);
    this.chosen = ko.observable(options.chosen);
    this.toggleItem = function () {
        self.chosen(!self.chosen());
    };
}

function myViewModel() {
    var self = this;
    self.Tags = ko.observableArray([
        new item({
        title: 'Tag1',
        level: 'Primary',
        chosen: true
    }),
        new item({
        title: 'Tag2',
        level: 'Primary',
        chosen: false
    }),
        new item({
        title: 'Tag3',
        level: 'Primary',
        chosen: false
    }),
        new item({
        title: 'Tag4',
        level: 'Primary',
        chosen: false
    }),
        new item({
        title: 'OtherTag',
        level: 'Secondary',
        chosen: false
    })]);


    self.PrimaryTags = ko.computed(function() {
        return ko.utils.arrayFilter(this.Tags(), function(tag) {
            return tag.level() === 'Primary';
        });
    }, self);
    self.SecondaryTags = ko.computed(function() {
        return ko.utils.arrayFilter(this.Tags(), function(tag) {
            return tag.level() === 'Secondary';
        });
    }, self);

}

var vm = new myViewModel();
ko.applyBindings(vm);

<strong>例:http://jsfiddle.net/andrewwhitaker/RepnY/1/

于 2012-10-10T00:13:27.647 に答える
2

observableArraysは、配列自体(追加/削除されるアイテムなど)のみを追跡します。chosenプロパティを監視可能にしてから、それを切り替える関数を追加することをお勧めします。

こちらのサンプル:http://jsfiddle.net/rniemeyer/7aVVy/

あなたの例から、あなたのマークアップは次のようになります:

<div data-bind="foreach: PrimaryTags" class='tag-grid'>
    <span class="tag-cell" data-bind="text: title, css: { chosen: chosen }, click: $parent.toggleChosen">
    </span>
</div>​

次のようなビューモデルを使用します。

function MyViewModel() {
    var self = this;
    self.Tags= ko.observableArray([
        {
        title: 'Tag1',
        level: 'Primary',
        chosen: ko.observable(true)},
    {
        title: 'Tag2',
        level: 'Primary',
        chosen: ko.observable(false) },
    {
        title: 'Tag3',
        level: 'Primary',
        chosen: ko.observable(false)},
    {
        title: 'Tag4',
        level: 'Primary',
        chosen: ko.observable(false)},
    {
        title: 'OtherTag',
        level: 'Secondary',
        chosen: ko.observable(false)}]);

    self.toggleChosen = function(tag) {
        tag.chosen(!tag.chosen());  
    };

    self.PrimaryTags = ko.computed(function() {
        return ko.utils.arrayFilter(self.Tags(), function(tag) {
            return tag.level === 'Primary';
        });
    });
    self.SecondaryTags = ko.computed(function() {
        return ko.utils.arrayFilter(self.Tags(), function(tag) {
            return tag.level === 'Secondary';
        });
    });
}
于 2012-10-10T00:13:46.387 に答える