2013-11-04 30 views
0
var modules; 

$.when(
    $.get('modules.json', function(data) { 
     var mapping = { 'observe' : ['enabled'] }; 
     modules = ko.mapping.fromJS(data, mapping); 
    }) 
).then(function() { 
    ko.applyBindings(new viewModel(modules)); 
}); 

function viewModel(modules) { 

    var self = this; 

    self.modules = modules; 

    console.log(self.modules()); 

    ... 

} 

不應該從JSON陣列中的每個模塊對象enabled鍵值顯示爲我設置什麼是在JSON中定義的值控制檯可觀察到的功能(在這種情況下true)?映值不成爲觀察的,等

另外,有什麼更好的方式等待綁定接收的json數據比我現在嘗試的方式(如果有更好的方法)?

從我的JSON數組對象看起來是這樣的:

{ 
    "id" : "spnsrlogo", 
    "name" : "Sponsor Logo", 
    "code" : "<h3>Sponsor Logo</h3><label for=\"spnsrLogoSrc\" data-bind=\"text: $root.spnsrLogoSrc\">Sponsor Logo Path</label><input type=\"text\" id=\"spnsrLogoSrc\" data-bind=\"value: $root.spnsrLogoSrc, valueUpdate: 'afterkeydown'\">", 
    "output" : "assets/img/sponsor-logo.png", 
    "enabled" : true 
} 

另外,我怎麼可以利用code值,以便當它被附加了可觀變得活躍?舉個例子:

<div> 
    <div data-bind="foreach: modules"> 
     <input type="checkbox" data-bind="checked: $parent.modulesEnabled(), value: $data.id, attr: { id: $data.id }"> 
     <label data-bind="attr: { for: $data.id }, text: $data.name" class="inlineblock"></label> 
    </div> 
</div> 
<div id="modulecontainer" data-bind="foreach: modules"> 
    <div class="moduleoptions" data-bind="visible: $parent.modulesEnabled(), html: code, attr: { id: 'module-' + $data.id}"></div> 
</div> 

我試着讓modulesEnabled一個可觀察的數組,但是沒有奏效。

任何幫助將不勝感激!

回答

0

如果有人有興趣,我終於成功讓事情順利進行。我要感謝pax162的第二個答案,因爲如果沒有它,我會迷失方向。

我結束了構建我的JSON像這樣:

{ 
    "id" : "isi", 
    "name" : "ISI", 
    "code" : "<h3>ISI</h3><label for=\"isiHeading\">ISI Heading</label><input type=\"text\" id=\"isiHeading\" data-bind=\"value: isiHeading, valueUpdate: 'afterkeydown'\"><label for=\"isiContent\">ISI Content</label><textarea id=\"isiContent\" data-bind=\"value: isiContent, valueUpdate: 'afterkeydown'\"></textarea><label for=\"isiFooter\">ISI Footer HTML</label><textarea id=\"isiFooter\" data-bind=\"value: isiFooter, valueUpdate: 'afterkeydown'\"></textarea>", 
    "observables" : ["isiHeading","isiContent","isiFooter"] 
} 

,然後用一點推遲jQuery的魔術和手動添加我的觀測:

$.when(
    $.get(options.paths.modules, function(data) { 
     self.modules = data; 
     for (var i=0, l=self.modules.length; i<l; i++) { 
      if (typeof(data[i].observables) !== "undefined") { 
       for (var j=0, ll=data[i].observables.length; j<ll; j++) { 
        self.modules[i][data[i].observables[j]] = ko.observable(''); 
       } 
      } 
      self.modules[i].enabled = ko.observable(true); 
     } 
    }) 
).then(function() { 
    self.successful(); 
    ko.applyBindings(self); 
}, function(o) { 
    console.log(o); 
}); 

如果有人好奇,我成功函數包含customHtml綁定處理程序定義並創建其他更一般的observable(我在其他地方使用(不依賴於收到的JSON)):

this.successful = function() { 

    ko.bindingHandlers.customHtml = { 
     init: function(element,valueAccessor,allBindings,viewModel,bindingContext) { 
      $(element).html(valueAccessor()); 
      ko.applyBindingsToNode($(element)[0],{with:viewModel}, bindingContext.$root); 
      return { controlsDescendantBindings: true }; 
     }, 
     update: function(element,valueAccessor,allBindings,viewModel,bindingContext) { 
      // 
     } 
    }; 

    // other functionality not relevant to this problem 

}; 
1

對於問題的第一部分,我瀏覽了映射源。在here左右的某處,觀察設置被處理。它的工作原理是將屬性的「完整路徑」與您在觀察數組中傳遞的字符串完全匹配。

使用您的json層次結構,啓用的屬性應該指定爲[0] .enabled,[1] .enabled,[2] .enabled等。目前我認爲你必須像這樣在數組中傳遞它們,也許我們應該問問其中一個插件維護者,如果它可以更改爲[i] .enabled之類的,以便考慮數組中的所有成員。如果任何維護者/ hardcore_users讀取這個:夥計們,我是否正確?

所以你必須要產生「觀察」配置陣列是隻要你在初始數據,項目的數量看起來像這樣:

var mapping = { 'observe' : ['[0].enabled', '[1].enabled', '[2].enabled',.../*and so on*/ ] }; 

它可能會更好改變你的json結構。

對於問題的第二部分,它可以用自定義綁定來完成,像這樣的:

ko.bindingHandlers.customHtml = { 
    init:function(element, valueAccessor, allBindings, viewModel, bindingContext){ 
     $(element).html(valueAccessor()); 
     ko.applyBindingsToNode($(element).find("div")[0],{with:viewModel}, bindingContext.$root);   
     return { controlsDescendantBindings: true };    
    }, 
    update:function(element, valueAccessor, allBindings, viewModel, bindingContext){        
    } 
} 

注意,我添加了一些div標籤包裝的HTML代碼中的性能。

在這樣的頁面變化的初步HTML,我只加了customHtml customBinding:

<div id="modulecontainer" data-bind="foreach: modules"> 
    <div class="moduleoptions" data-bind="visible: $parent.modulesEnabled(), customHtml: code, attr: { id: 'module-' + $data.id}"></div> 
</div> 

最後,所有代碼的小提琴:http://jsfiddle.net/cUVN8/3/