2012-10-09 11 views
3

我对Knockout.js相当陌生,所以我可能只是缺少一些东西。我正在尝试创建一组按钮,其中的'selected'状态反映了数组中项目的子值。将css类绑定到Observable Array item.chosen与knockout.js的值

见本小提琴: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的初始显示是正确的。看来我可以使click事件更改observable数组中的值而不会出现问题。显示的div不会改变css类来响应这个。

我意识到,作为数组中项目的对象的孩子本身并不是可观察的。但是,我不应该呼吁valueHasMutated()强制该问题?这可能也不是完成行为的最优雅的方式。

任何人都想帮助一个学习JavaScript的人出去?

+0

两个优秀的答案,谢谢!我选择安德鲁的主要原因是我从中学到了更多关于淘汰赛的信息,但都是不错的选择。我会使用RP的方法来获得更通用的“任何可以选择的”场景,但是我认为将它作为单个对象可能更适合我的使用。 – Chris

回答

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); 

例子:http://jsfiddle.net/andrewwhitaker/RepnY/1/

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'; 
     }); 
    }); 
} 
相关问题