当可观察数组更新时,不会调用Knockout kobindinghandler更新

时间:2015-03-27 00:42:49

标签: jquery jquery-ui knockout.js jquery-ui-accordion

我正在尝试创建一个jquery ui accordion,在我向基础可观察量array添加值时会更新。我正在jquery1.9.0, jquery-ui-1.11.2使用knockout 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加载数组)。

由于

2 个答案:

答案 0 :(得分:1)

我已经对此进行了一些研究,在使用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活页夹。

答案 1 :(得分:0)

由于您未将update中的任何值提供给viewmodel活页夹,因此不会在您的情况下调用accordion

  

当绑定应用于元素并且跟踪您访问的任何依赖项(observables / computeds)时,Knockout将最初调用更新回调。当任何这些依赖项发生更改时,将再次调用更新回调

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

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

现在,在更改account_data时,系统会调用使用viewmodel的活页夹。