可观察数组更新时未调用 Knockout kobindinghandler 更新

Knockout kobindinghandler update not being called when observable array updated

我正在尝试创建一个 jquery ui accordion,当我将值添加到底层可观察对象 array 时它会更新。我将 jquery1.9.0, jquery-ui-1.11.2knockout 3.2.0 一起使用,并尽可能地简化了示例。

我是淘汰赛的新手,也是 javascript 的新手。我还尝试了敲除教程页面上的示例,看看它是否可行。我正在创建一个简单的 div/h3/div 块,它是从一个可观察数组生成的,当新元素添加到数组时工作正常,显示新数据,但它不会重新生成手风琴。

我尝试了几种方法,其中一种方法在将添加到数组的函数中进行了手风琴刷新,但我已经阅读(并相信)更好的解决方案是使用 kobindinghandler。这适用于数组中的初始数据,因为手风琴是生成的,但是当添加新元素时,它不会调用处理程序中的更新函数。

ko.bindingHandlers.accordion = {
  init: function(element, valueAccessor) {
    $(element).accordion();
  },
  update: function(element, valueAccessor) {
    var options = valueAccessor() || {};
    $(element).accordion("refresh");
  }
};

var viewModelInst = {
  account_data: ko.observableArray([{
    account_id: 1,
    name: "account1"
  }, {
    account_id: 2,
    name: "account2"
  }])
};


ko.applyBindings(viewModelInst);


setTimeout(function() {
  viewModelInst.account_data.push({
    account_id: 3,
    name: 'test'
  });
}, 3000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/themes/smoothness/jquery-ui.css" />

<body>
  <div data-bind="foreach: account_data, accordion">
    <h3 data-bind="text: name"></h3>
    <div>
      <p>some text</p>
    </div>
  </div>
</body>

也许我把它简化得太多了,你可以提供任何帮助来让这个工作或实现相同结果的替代方法(这里的最终结果是从 REST 加载数组 api ).

谢谢

在您的情况下不会调用 update,因为您没有将 viewmodel 中的任何值提供给 accordion 活页夹。

Knockout will call the update callback initially when the binding is applied to an element and track any dependencies (observables/computeds) that you access. When any of these dependencies change, the update callback will be called once again

下面的代码可能适用于您的情况。

<div data-bind="foreach: account_data, accordion: account_data">
<h3 data-bind="text: name"></h3>
<div>
  <p>some text</p>
</div>

现在,在更改 account_data 时,将调用使用 viewmodel 的绑定器。

我在这方面做了更多的工作,问了几位同事,并在使用 bindingHandlers 时从一个工作示例中提取了代码,将其重新应用到我的示例中。如果加上下面两行代码,看来update方法调用成功了:

var value = valueAccessor(); var valueUnwrapped = ko.unwrap(value);

我实际上并没有对这些值做任何事情,但这足以让处理程序执行,所以当我有以下 $(element).accordion("refresh"); 时,它会按预期工作。完整的处理程序代码是:

ko.bindingHandlers.accordion = { init: function(element, valueAccessor) { $(element).accordion(); }, update: function(element, valueAccessor) { var value = valueAccessor(); var valueUnwrapped = ko.unwrap(value); $(element).accordion("refresh"); } };

您还必须将 account_data 传递给 accordion 活页夹。