List refresh after ajax call using Knockout JS

I have a list of attachments on a page that is created by calling jQuery $.ajax and JS knockout.

My HTML looks like (this disappears):

 <tbody data-bind="foreach: attachments"> <tr> <td data-bind="text: Filename" /> </tr> </tbody> 

I have a function that gets a list of attachments that is returned as a JSON response:

 $(function () { getFormAttachments(); }); function getAttachments() { var request = $.ajax({ type: "GET", datatype: "json", url: "/Attachment/GetAttachments" }); request.done(function (response) { ko.applyBindings(new vm(response)); }); } 

My model looks like this:

 function vm(response) { this.attachments = ko.observableArray(response); }; 

There is an update button that you can use to update this list, because added / deleted time attachments can be added / removed:

 $(function () { $("#refresh").on("click", getAttachments); }); 

The initial rendering of the attachment list is fine, however, when I call getAttachments again using the refresh button, click on the list added to (in fact, each item is duplicated several times).

I created jsFiddle to demonstrate this problem here:

http://jsfiddle.net/CpdbJ/137

What am I doing wrong?

+7
source share
1 answer

Here is the fiddle that fixes your sample. The biggest problem was what you called "applyBindings" several times. In general, you will call applyBindings to load the page, and then the page will interact with the View Model to force Knockout to update parts of your page.

http://jsfiddle.net/CpdbJ/136

html

 <table> <thead> <tr><th>File Name</th></tr> </thead> <tbody data-bind="foreach: attachments"> <tr><td data-bind="text: Filename" /></tr> </tbody> </table> <button data-bind="click: refresh">Refresh</button> 

Javascript

 $(function () { var ViewModel = function() { var self = this; self.count = 0; self.getAttachments = function() { var data = [{ Filename: "f"+(self.count*2+1)+".doc" }, { Filename: "f"+(self.count*2+2)+".doc"}]; self.count = self.count + 1; return data; } self.attachments = ko.observableArray(self.getAttachments()); self.refresh = function() { self.attachments(self.getAttachments()); } }; ko.applyBindings(new ViewModel()); }); 

-

You can also see the mapping plugin - http://knockoutjs.com/documentation/plugins-mapping.html . This can help you convert JSON to View Models. In addition, it can set the property as a “key” for an object ... this will be used to identify old and new objects in subsequent comparisons.

Here is a script I wrote some time ago to demonstrate a similar idea:

http://jsfiddle.net/wgZ59/276

NOTE. I use "update" as part of the matching rules, but ONLY so that I can enter the console. You will need to add this only if you want to customize the way the plugin objects are updated.

+10
source

All Articles