Knockout:错误:刷新页面时,无法多次将绑定应用于同一元素

时间:2014-11-10 08:14:50

标签: javascript knockout.js

我正在使用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时如何避免错误?

1 个答案:

答案 0 :(得分: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();

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

ko.applyBindings(actualViewModel);

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

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

必须成为

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