2013-10-17 34 views
4

我目前正在編寫一個自定義綁定處理程序來在我們的頁面中形成一個控件。
此控件生成自己的viewmodel或主viewmodel的一個孩子,以不改變原始viewmodel。 (該控件的實現不是頁面的關注)

代碼示例
我創建了一個抽象的例子:
http://jsfiddle.net/jdarn/

JS:

ko.bindingHandlers.subBinding = { 
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var actualValue = valueAccessor(); 

     ko.virtualElements.emptyNode(element); 

     var subViewModel = {}; 
     subViewModel.subValue = 
      new ko.observable(ko.utils.unwrapObservable(actualValue) * 2); 

     var childBindingContext = bindingContext.createChildContext(viewModel); 
     ko.utils.extend(childBindingContext, subViewModel); 

     var getDomNodesFromHtml = function(html) { 
      var div = document.createElement('div'); 
      div.innerHTML = html; 
      var elements = div.childNodes; 
      var arr = []; 
      for(var i = 0; i < elements.length; i++) { 
       arr.push(elements[i]); 
      } 
      return arr; 
     }; 

     var html = '<p data-bind="text: subValue"></p>' + 
      '<pre data-bind="text: JSON.stringify(ko.toJS($data), null, 4)"></pre>'; 

     ko.virtualElements.setDomNodeChildren(element, getDomNodesFromHtml(html)); 
     ko.applyBindingsToDescendants(childBindingContext, element); 

     return { controlsDescendantBindings: true }; 
    }, 
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
    } 
}; 
ko.virtualElements.allowedBindings.subBinding = true; 

var mainViewModel = { 
    value1: new ko.observable(100), 
    value2: new ko.observable(200) 
}; 
ko.applyBindings(mainViewModel, document.getElementById('main')); 

HTML:

<div id="main"> 
    <p>Main viewmodel:</p> 
    <pre data-bind="text: JSON.stringify(ko.toJS($data), null, 4)"></pre> 

    <hr /> 

    <!-- ko subBinding: value2 --> 
    <!-- /ko --> 
</div> 

問題
$數據上可用的bindinghandlers'視圖模型實際上是父(主)視圖模型。這似乎是奇怪的行爲,因爲subValue等其他屬性實際上綁定正確。這些屬性在主視圖模型中不存在。

臆測
我的猜測是,綁定發生後,僅在返回的controlsDescendantBindings。因此,主視圖模型滲透。 KO然後贊成主視圖模式上下文中存在的$數據。

問題
(考慮到我的猜測是正確的)
是否有創建和綁定子視圖模型到一個適當的方式(虛擬的,在這種情況下)bindinghandlers自己的控制?

回答

4

感嘆,主要疏忽。

我根據我的一個文檔頁面上的執行情況:
http://jsfiddle.net/jdarn/2/

變化:
http://knockoutjs.com/documentation/custom-bindings-controlling-descendant-bindings.html

更新的代碼可以在這裏找到

var childBindingContext = bindingContext.createChildContext(viewModel); 
ko.utils.extend(childBindingContext, subViewModel); 

變得

var childBindingContext = bindingContext.createChildContext(subViewModel); 

我錯誤地解釋了createChildContext接受的參數 - 此參數是子級上下文中的viewModel。

-

控制的HTML片段變成:

var html = '<p data-bind="text: subValue"></p>' + 
     'data: <pre data-bind="text: JSON.stringify(ko.toJS($data), null, 4)"></pre>' + 
     'parent: <pre data-bind="text: JSON.stringify(ko.toJS($parent), null, 4)"></pre>' + 
     'root through parentcontext: <pre data-bind="text: JSON.stringify(ko.toJS($parentContext.$root), null, 4)"></pre>' + 
     'root (not working): <pre data-bind="text: JSON.stringify(ko.toJS($root), null, 4)></pre>'; 
+0

四年後,這個剛剛引起了燈泡的時刻,固定我的問題,謝謝:)不知道有多少人被拋出那個文檔? – Whelkaholism

相關問題