【问题标题】:Refreshing list after ajax call with Knockout JS使用 Knockout JS 进行 ajax 调用后刷新列表
【发布时间】:2012-03-22 07:10:58
【问题描述】:

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

我的 HTML 看起来像(这被剥离了):

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

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

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

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

  request.done(function (response) {
    ko.applyBindings(new vm(response));
  });
}

我的视图模型如下所示:

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

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

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

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

我在这里创建了一个 jsFiddle 来演示这个问题:

http://jsfiddle.net/CpdbJ/137

我做错了什么?

【问题讨论】:

  • Kev - 好帖子。我仍然对此感到有些困惑。新的淘汰赛。我只是在页面加载时加载带有 AJAX 数据的 ViewModel 时遇到了类似的问题。我确定我错过了一个微小但严重的问题。让我感到困惑的一件事是一些教程将viewmodel 显示为一个对象(例如var viewmodel = { something: ko.observable() }),而另一些则显示为一个函数(例如function ViewModel() { this.something = ko.observable() }) - 有什么建议吗?
  • @one.beat.consumer - 请参阅我的后续问题:stackoverflow.com/questions/9589419/… - 答案和下面的 cmets 应该让事情更清楚。我建议花 25 美元看这个:pluralsight-training.net/microsoft/Courses/…
  • 我会看看你的另一个问题;谢谢。我订阅了复数视力,我已经看了 2-3 次......他们几乎没有触及表面,而且现在 2.0 已经发布,其中大部分内容已经过时,他们使用的是 1.2 或 1.3 测试版......

标签: javascript knockout.js


【解决方案1】:

这是一个修复您的示例的小提琴。您最大的问题是您多次调用“applyBindings”。通常,您将在页面加载时调用 applyBindings,然后页面将与 View Model 交互以使 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>

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());
});

--

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

这是我不久前写的一个小提琴来演示类似的想法:

http://jsfiddle.net/wgZ59/276

注意:我使用“更新”作为映射规则的一部分,但仅用于登录控制台。如果您想自定义映射插件如何更新对象,您只需要添加它。

【讨论】:

  • 如果说我没有数据,我需要调用 Ajax 方法和它的 GET,这将如何工作?
  • 只需更改 getAttachments 调用以进行 AJAX 调用,并在回调中将结果直接设置到附件可观察数组中。刷新只会调用 self.getAttachments()。附件将被初始化为空,然后您可以立即调用 self.getAttachments() 进行第一次 AJAX 调用。一旦回调设置结果,Knockout 将负责刷新您的 UI。
  • 嗯,由于某种原因,我无法使用此方法刷新数据,请参阅我的问题:stackoverflow.com/questions/21558075/…
猜你喜欢
  • 2014-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
  • 2018-12-30
  • 1970-01-01
  • 1970-01-01
  • 2012-08-28
相关资源
最近更新 更多