javascript – 在durandal中长时间运行加载操作

前端之家收集整理的这篇文章主要介绍了javascript – 在durandal中长时间运行加载操作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试找出运行长时间运行加载操作的最佳位置是使用Durandal.

据我所知,加载数据的一般建议是在viewmodel的activate方法中,这就是我通常所做的事情 – 类似于:

  1. viewmodel.activate = function () {
  2. var loadPromise = myService.loadData();
  3.  
  4. return $.when(loadPromise).then(function (loadedData) {
  5. viewmodel.data(data);
  6. });
  7. };

我知道如果我不在这里回复承诺,那么绑定通常会出现问题 – 如this question and answer indicates.

但是,在activate方法中执行长时间运行的加载操作会使应用程序在加载操作完成时“冻结”.例如,如果我的负载现在是这样的呢?

  1. viewmodel.activate = function () {
  2. // All loads return a promise
  3. var firstLoad = myService.loadFirstData();
  4. var secondLoad = myService.loadSecondData();
  5. var thirdLoad = myService.loadThirdDataWhichTakesAges();
  6.  
  7. return $.when(firstLoad,secondLoad,thirdLoad).then(function (one,two,three) {
  8. viewmodel.one(one);
  9. viewmodel.two(two);
  10. viewmodel.three(three);
  11. });
  12. };

在这种情况下,URL会更新以反映正在加载的页面,但页面内容仍然显示上一页(我的意思是“冻结”).

理想情况下,如果URL应更改为新页面,并且页面内容也应显示页面(即使尚未返回该页面的数据),也会很好.然后,当每个加载操作返回时,当数据绑定到视图模型时,应更新页面的相关部分.

是否有推荐的方法在Durandal内部实现这一目标?

我目前的解决方案是在activate方法中启动加载,然后在viewAttached方法中填充数据:

  1. var loadPromise;
  2.  
  3. viewmodel.activate = function () {
  4. // All loads return a promise
  5. var firstLoad = myService.loadFirstData();
  6. var secondLoad = myService.loadSecondData();
  7. var thirdLoad = myService.loadThirdDataWhichTakesAges();
  8.  
  9. loadPromise = $.when(firstLoad,thirdLoad);
  10.  
  11. // Don't return the promise - let activation proceed.
  12. };
  13.  
  14. viewmodel.viewAttached = function () {
  15. $.when(loadPromise).then(function (one,three) {
  16. viewmodel.one(one);
  17. viewmodel.two(two);
  18. viewmodel.three(three);
  19. });
  20. };

它似乎工作,但我记得在某处依赖viewAttached阅读并不是一个好的解决方案.我也不确定是否存在竞争条件,因为我允许激活继续进行.

还有其他建议吗?

解决方法

你不必返回一个promise,但是在这种情况下你必须在你的敲除绑定中处理这个,所以你不会绑定到未定义的元素.您可以尝试在激活中删除“返回”,但添加一个属性,指示模型是否仍在加载.像这样的东西:
  1. viewmodel.isLoading = ko.observable(false);
  2. viewmodel.activate = function () {
  3. isLoading(true);
  4. var loadPromise = myService.loadData();
  5.  
  6. $.when(loadPromise).then(function (loadedData) {
  7. viewmodel.data(data);
  8. isLoading(false);
  9. });
  10. };

然后,在您的视图中,您可以在视图仍在加载时显示一个部分,在加载完成时显示一个部分.有些人喜欢:

  1. <div data-bind:"visible: isLoading()">Loading Data....</div>
  2. <div data-bind:"visible: !isLoading()">Put your regular view with bindings here. Loading is done so bindings will work.</div>

猜你在找的JavaScript相关文章