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

为了更新绑定的属性,您必须使有问题的属性可观察。此外,您不需要 jQuery 来处理click事件,您可以使用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属性可观察,然后添加一个函数来切换它。

Sample here: http://jsfiddle.net/rniemeyer/7aVVy/

From your example, your markup might look like:

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

with your view model like:

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 回答