使用Knockout JS调用ajax后的刷新列表

Kev*_*Kev 7 javascript knockout.js

我在页面上有一个附件列表,它是使用jQuery $.ajax调用和Knockout JS生成的.

我的HTML看起来像(这被删除):

<tbody data-bind="foreach: attachments">
  <tr>
    <td data-bind="text: Filename" />
  </tr>
</tbody>
Run Code Online (Sandbox Code Playgroud)

我有一个函数,它获取作为JSON响应返回的附件列表:

$(function () {
  getFormAttachments();
});

function getAttachments() {
  var request = $.ajax({
    type: "GET",
    datatype: "json",
    url: "/Attachment/GetAttachments"
  });

  request.done(function (response) {
    ko.applyBindings(new vm(response));
  });
}
Run Code Online (Sandbox Code Playgroud)

我的视图模型看起来像:

function vm(response) {
  this.attachments = ko.observableArray(response);
};
Run Code Online (Sandbox Code Playgroud)

有一个刷新按钮,用户可以单击以刷新此列表,因为随着时间的推移,可能已添加/删除附件:

$(function () {
  $("#refresh").on("click", getAttachments);
});
Run Code Online (Sandbox Code Playgroud)

附件列表的初始呈现很好,但是当我getAttachments通过刷新按钮再次调用时,单击列表被添加到(实际上每个项目都重复多次).

我已经创建了一个jsFiddle来演示这个问题:

http://jsfiddle.net/CpdbJ/137

我究竟做错了什么?

Joh*_*les 10

这是一个修复你的样本的小提琴.你最大的问题是你多次调用'applyBindings'.通常,您将在页面加载时调用applyBindings,然后页面将与视图模型交互以使Knockout刷新页面的某些部分.

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>
Run Code Online (Sandbox Code Playgroud)

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());
});
Run Code Online (Sandbox Code Playgroud)

-

您可能还想查看映射插件 - http://knockoutjs.com/documentation/plugins-mapping.html.它可以帮助您将JSON转换为View模型.此外,它还可以将属性指定为对象的"键"...这将用于在后续映射中确定旧对象和新对象.

这是一个小提琴,我写了一段时间,以证明一个类似的想法:

http://jsfiddle.net/wgZ59/276

注意:我使用'update'作为映射规则的一部分,但只能这样我才能登录到控制台.如果要自定义映射插件更新对象的方式,则只需添加此项.