我正在尝试找出运行长时间运行加载操作的最佳位置是使用 Durandal。
据我所知,加载数据的一般建议是在 ViewModel 的activate
方法中,这是我通常所做的 - 类似于:
viewModel.activate = function () {
var loadPromise = myService.loadData();
return $.when(loadPromise).then(function (loadedData) {
viewModel.data(data);
});
};
我知道,如果我不在这里返回承诺,那么绑定通常会出现问题 - 正如这个问题和答案所表明的那样。
但是,在该方法中执行长时间运行的加载操作activate
会使应用程序在加载操作完成时“冻结”。例如,如果我的负载现在是这样的怎么办?
viewModel.activate = function () {
// All loads return a promise
var firstLoad = myService.loadFirstData();
var secondLoad = myService.loadSecondData();
var thirdLoad = myService.loadThirdDataWhichTakesAges();
return $.when(firstLoad, secondLoad, thirdLoad).then(function (one, two, three) {
viewModel.one(one);
viewModel.two(two);
viewModel.three(three);
});
};
在这种情况下,URL 会更新以反映正在加载的页面,但页面内容仍显示前一页(这就是我所说的“冻结”)。
理想情况下,最好将 URL 更改为新页面,并且页面内容也应该显示新页面(即使该页面的数据尚未返回)。然后,随着每个加载操作返回,页面的相关部分应该在数据绑定到视图模型时更新。
有没有推荐的方法可以在 Durandal 内部实现这一目标?
我目前的解决方案是在方法中启动负载activate
,然后在方法中填充数据viewAttached
:
var loadPromise;
viewModel.activate = function () {
// All loads return a promise
var firstLoad = myService.loadFirstData();
var secondLoad = myService.loadSecondData();
var thirdLoad = myService.loadThirdDataWhichTakesAges();
loadPromise = $.when(firstLoad, secondLoad, thirdLoad);
// Don't return the promise - let activation proceed.
};
viewModel.viewAttached = function () {
$.when(loadPromise).then(function (one, two, three) {
viewModel.one(one);
viewModel.two(two);
viewModel.three(three);
});
};
它似乎有效,但我记得在某处阅读过依赖viewAttached
不是一个好的解决方案。我也不确定是否存在竞争条件,因为我允许激活继续。
还有其他建议吗?