【问题标题】:durandal knockout - strange binding / timing error?durandal 淘汰赛 - 奇怪的绑定/计时错误?
【发布时间】:2013-06-01 12:24:27
【问题描述】:

我遇到了一些奇怪的绑定/计时行为 - 我已经粘贴了相关代码。当我在 chrome 中手动缓慢地逐步执行代码时,当我让它正常运行时,它会正确填充我的下拉列表,但它不会....我做错了什么?我已经输入了控制台输出,其中我的“获得省份”的时间不同。

 var provinces = ko.observableArray();

 var vm = {
        activate: activate,
        viewAttached:viewAttached,
        title: 'Home View',
        provinces: provinces,
    };

return vm;

  function activate() {
            getProvinces(provinces);
            return true;
    }

function viewAttached() {
    console.log("got data");
}  

简单的 ajax 调用如下,我传入我的 observable(这几乎完全来自 John Papa 复数演示):

getProvinces: function (observableArray) {
   observableArray([]);

   var options = {
        url: currentServer + 'regions/GetInUseProvinces',
        type: 'GET',
        async: true,
        dataType: "json",
    };

    $.ajax(options).then(querySucceded);

    function querySucceded(data) {
        var provinces = [];
        data.forEach(function(item) {
            var s = new MedappData.Data.Province(item.Name, item.ID);
            provinces.push(s);
        });
        observableArray(provinces);
        console.log('got provinces');
    }
},  

两者的控制台输出不同如下。

当我手动输入断点并逐步执行时,我得到以下信息,并且效果很好:

["Activating", Object]
["[viewmodels/shell] ", "Medapp loaded..."] system.js:62
["Activating Route", Object, Object, n.Object]
["Activating", Object]
["Binding", "views/shell", Object]
got provinces vendor:5319
["Binding", "views/nav", ko.bindingContext]
["Binding", "views/home", Object]
["Binding", "views/footer", ko.bindingContext]
got data

当我删除断点并让它运行时,输出如下所示,并且没有填充任何内容。

["Activating", Object]
["[viewmodels/shell] ", "Medapp loaded..."] system.js:62
["Activating Route", Object, Object, n.Object]
["Activating", Object]
["Binding", "views/shell", Object]
["Binding", "views/nav", ko.bindingContext]
["Binding", "views/home", Object]
["Binding", "views/footer", ko.bindingContext]
got provinces vendor:5319
got data 

【问题讨论】:

  • 解决这个问题的方法是从 activate() 事件中删除我的填充方法,并将其放入 viewAttached() 事件中。这似乎解决了问题......但是我不确定我是否理解......我似乎在任何地方都读到 activate() 是加载数据的地方???

标签: durandal


【解决方案1】:

getProvinces 是异步操作,因此您必须返回一个 Promise 以允许 Durandal 确定何时允许继续编写。在异步操作后返回 true 不会这样做。

$.ajax(... 已经返回了一个承诺,所以将getProvinces 更改为

return $.ajax(options).then(querySucceded);

activate

function activate() {
    return getProvinces(provinces);
}

应该可以解决问题。

【讨论】:

  • 一如既往,你的 sn-p 解决了我的噩梦。
  • 是的。当你进行异步调用时,你没有告诉 Durandal 在继续之前等待它。您可以通过从异步调用返回承诺来做到这一点,如此处所示。它在调试器中工作,因为当您单步执行它时,它有足够的时间在您单步执行时完成:)
  • 这正是我所缺少的。然而,这确实带来了一个问题。如果您有多个待处理的异步任务(例如获取多种不同的数据类型),那么 && 对 activate 的返回值的承诺是否有意义?
  • return $.when(...) 可能是您正在寻找的。顺便说一句:不要劫持问题,问新问题;-)。
猜你喜欢
  • 2014-08-01
  • 2015-06-27
  • 2013-04-09
  • 2014-04-11
  • 1970-01-01
  • 2013-02-04
  • 2015-02-24
  • 2014-04-16
  • 1970-01-01
相关资源
最近更新 更多