Knockout observableArray not updating JQuery Accor

2019-08-29 05:50发布

问题:

I have updated my website to the latest JQuery, JQueryUI and KnockOutJS.

Since then my accordion refuses to update when I add items to my observerable array. This works just fine when using KnocKOutJS version 2.0.0 with older versions for JQuery.

I have recreated the problem in JSFiddler and would appreciate any help. The javascript is a heavily simplified version of my actual code.

http://jsfiddle.net/glenb/M9222/6/

Any assistance would be greatly appreciated. My Model looks like this:

function ModelCollection() {
   var self = this;
   self.ModelItems = ko.observableArray([]);

   self.AddNewItem = function(){
      var newItem = new ModelItem();
      newItem.Name = "Added";
      modelCollectionApp.ModelItems.push(newItem);
  };
}

function ModelItem() {
   var self = this;
   self.Name = "";
}

The HTML:

<div id="knockOutBinding">
   <div data-bind="foreach: ModelItems, jqAccordion: {}">
      <h3>An Element Title</h3>
      <div>Some Content</div>
   </div>
   <button data-bind="click: AddNewItem">Add New Item</button>
</div>

Finally I initially populate it and bind it

var modelCollectionApp = new ModelCollection();

var modelItem = new ModelItem();
modelItem.Name = "test1";
modelCollectionApp.ModelItems.push(modelItem);

var modelItem = new ModelItem();
modelItem.Name = "test2";
modelCollectionApp.ModelItems.push(modelItem);

ko.applyBindings(modelCollectionApp, document.getElementById("knockOutBinding"));

回答1:

So turns out that things have changed quiet drastically with regards to JQueryUI Widgets and Knockout in version 3.

Evan explains here https://groups.google.com/forum/#!searchin/knockoutjs/accordion/knockoutjs/OX6Lp_I_LoY/472sLkF5MTcJ

Bottom line is when binding the accordion in my code:

<div data-bind="foreach: ModelItems, jqAccordion: {collapsible: true}">

Before, you would pass in your config options like "{collapsible: true}". This worked in older versions but now it has changed. You should pass in the "ViewModel" instead.

<div data-bind="foreach: ModelItems, jqAccordion: ModelItems">

The other thing that needed to change was in the update method you have to call ko.unwrap

var options = valueAccessor();
ko.unwrap(options)  // <-- this is important!

If you want to customize the accordion, you have to do it in the init section of the binding like this:

init: function (element, valueAccessor) {
   var options = {
      collapsible: true,
      active: false,
      animate: "easeOutQuint",
      heightStyle: "content"
   };

   $(element).accordion(options);
   $(element).bind("valueChanged", function () {
      ko.bindingHandlers.jqAccordion.update(element, valueAccessor);
   });
}

Here is the updated JSFiddle http://jsfiddle.net/glenb/M9222/7/

I hope this helps someone out there, upvote if it helped you!