【问题标题】:Knockout: Error: You cannot apply bindings multiple times to the same element when refreshing page淘汰赛:错误:刷新页面时,您不能多次将绑定应用于同一元素
【发布时间】:2015-01-06 11:55:43
【问题描述】:

我正在使用 Knockout 绑定 MVC 视图。这第一次运行良好,但对于后续刷新,Knockout 会引发错误:

错误:您不能对同一个元素多次应用绑定。

这是我的绑定代码(在 Document.Ready 中),注意我使用 setTimeout 每 25 秒运行一次,这就是错误发生的地方:

function viewModel() {
      Loading = ko.observable(true),
      CurrentUser = ko.observable(),
      Environments = ko.observableArray(),
      CurrentFormattedDate = ko.observable()
   }   

function doPoll() {
             $.get("/home/getindex")
                 .done(function (data) {
                     $(data).each(function (index, element) {
                         viewModel = data;
                         viewModel.Loading = false;
                         viewModel.CurrentFormattedDate = moment().format('MMMM YYYY');
                     });
                     ko.applyBindings(viewModel);                     
                 })
                 .always(function () {
                     setTimeout(doPoll, 25000);
                 })
                 .error(function (ex) {
                     alert("Error");
                 });
            };

            doPoll();

DoPoll 被多次调用时如何避免错误?

【问题讨论】:

  • 你为什么使用$(data).each?您似乎从不使用 index/element 参数,而只是在循环中更新同一个对象。结果将等同于根本不使用循环。另外,我的 viewModel 对象是错误的。您需要将this 放入成员初始化中,例如this.Loading = ...,否则假定的成员将成为全局 变量,这在JS 中是不好的做法!。
  • 啊,好地方。该模型以前绑定到一个集合,我忽略了更新代码!

标签: javascript knockout.js


【解决方案1】:

默认情况下,Knockout 中的绑定每个 dom 元素只能发生一次。 ko.aplyBindings 会将绑定应用到文档正文,因此当您从 doPoll 函数第二次调用它时,它将已经与数据绑定。

一种可能的解决方案是让您当前的视图模型成为新视图模型的可观察属性;然后只更新 observable 属性:

var actualViewModel = {
    innerViewModel: ko.observable(new viewModel());
}   

function doPoll() {
    $.get("/home/getindex")
       .done(function (data) {
           $(data).each(function (index, element) {
                   data.Loading = false;
                   data.CurrentFormattedDate = moment().format('MMMM YYYY');
                   actualViewModel.innerViewModel(data);
               });                  
           })
       .always(function () {
                setTimeout(doPoll, 25000);
           })
       .error(function (ex) {
                alert("Error");
           });
 };

 doPoll();

您需要针对新视图模型调用 initial 绑定:

ko.applyBindings(actualViewModel);

您还需要更新绑定中访问属性的方式,将 innerViewModel 放在前面 - 例如:

<div data-bind="text: CurrentFormattedDate">...</div> 

必须变成

<div data-bind="text: innerViewModel.CurrentFormattedDate">...</div>

【讨论】:

  • 谢谢你的提示,我试试看。
猜你喜欢
  • 2016-04-29
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 2017-05-05
  • 2013-07-16
  • 2014-01-22
  • 2014-04-13
相关资源
最近更新 更多