2012-10-09 60 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'; 
     }); 
    }); 
} 
相關問題