淘汰视图模型绑定

时间:2013-10-09 20:29:53

标签: knockout.js knockout-2.0

假设我有一张桌子:

<table>
 <tr class="expandable">
  <td><button>Expand</button></td>
  <td>Parent information #1</td>
  <td>Parent information #2</td>
 </tr>
 <tr class="expandable">
  <td><button>Expand</button></td>
  <td>Parent information #1</td>
  <td>Parent information #2</td>
 </tr>
</table>

我有一个淘汰模板:

<script type="text/html" id="child-template">
 <!-- ko foreach: children -->
  <tr>
   <td></td>
   <td>Child information #1</td>
   <td>Child information #2</td>
  </tr>
 <!-- /ko -->
</script>

还有一些javascript

$('button').click(function() {
 $.getJSON(url, function(items) {
  var template = $('#child-template').html();
  $(this).closest('tr').after(template);
  var viewModel = { children: ko.observableArray(items) };
  ko.applyBindings(viewModel);
 });
});

我想要的是一个包含父行的表。如果我点击父行,我会通过ajax调用它的子节点。当我找到孩子时,我想为父母行下的每个孩子展示一张桌子。

上述代码的问题在于我将绑定应用于整个页面。我真正想要的是将该视图模型仅绑定到该父行。如果我第一次单击父行#1,它将显示正确的子项,但是当我单击父行#2时,两个子列表将包含相同的项目。

我在JSFiddle中可视化我的问题:http://jsfiddle.net/6ehfb/1/

如果您首先单击父行#1上的展开,它将显示子项目#1。单击父行#2上的展开时,两个子列表都包含相同的项目。扩展父行#2时,不应影响父行#1的​​子节点。

如何解决?

1 个答案:

答案 0 :(得分:3)

可能的解决方法是定义包含父项集合的单个视图模型。这意味着每个家长都可以拥有独立的孩子阵列。

function generateParent(name, id)
{
    function show() {
        this.expanded(true);
    }

    function initalDataCollection() {
        // Get data, add data to model
        // ...

        this.expanded(true);
        this.showAction(show);
    }

    return {
        expanded: ko.observable(false),
        information: ko.observable(name),
        children: ko.observableArray(),
        showAction: ko.observable(initalDataCollection)
    };
}

var viewModel = {
    parents: ko.observableArray()
};

//Add parent data to model
// ...

ko.applyBindings(viewModel);

我提供了一个可以在http://jsfiddle.net/MatthewDunsdon/khMG8/

找到的工作解决方案

HTML:

<table border="1" data-bind="foreach: parents">
     <tr class="expandable">
        <td>
            <button data-bind="visible: !expanded(), click: showAction() ">Expand</button>
            <button data-bind="visible: expanded(), click: function() { expanded(false) }">Hide</button>
         </td>
        <td><span data-bind="text: information"></span></td>
     </tr>
    <!-- ko if: expanded -->
    <!-- ko foreach: children -->
    <tr>
        <td></td>
        <td data-bind="text: info"></td>
    </tr>
    <!-- /ko -->
    <!-- /ko -->

</table>

旁注:作为此解决方案的一部分,我让敲除处理onClick事件(“扩展”功能)并更新页面上的html。