Note that there are some explanatory texts on larger screens.

plurals
  1. POLong running load operations in durandal
    text
    copied!<p>I'm trying to work out where the best place to run a long-running load operation is using Durandal.</p> <p>From what I can tell, the general recommendation for loading data is in the ViewModel's <code>activate</code> method, which is what I usually do - something like:</p> <pre><code>viewModel.activate = function () { var loadPromise = myService.loadData(); return $.when(loadPromise).then(function (loadedData) { viewModel.data(data); }); }; </code></pre> <p>I know that if I don't return the promise here, then there's usually problems with the bindings - as <a href="https://stackoverflow.com/questions/16872689/durandal-knockout-strange-binding-timing-error">this question and answer indicates</a>.</p> <p>However, executing a long running load operation in the <code>activate</code> method makes the app "freeze" while the load operation completes. For example, what if my load was now something like this?</p> <pre><code>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); }); }; </code></pre> <p>In this scenario, the URL is updated to reflect the page which is being loaded, but the page content still shows the previous page (which is what I mean by "freezes").</p> <p>Ideally, it would be good if the URL should change to the new page, and the page content should show the new page too (even though the data for that page has not yet been returned). Then, as each load operation returns, the relevant part of the page should be updated when the data is bound into the view model.</p> <p><strong>Is there a recommended way for achieving this inside Durandal?</strong></p> <p>My current solution is to kick-off the load in the <code>activate</code> method, and then populate the data in the <code>viewAttached</code> method:</p> <pre><code>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); }); }; </code></pre> <p>It <em>seems</em> to work, but I remember reading somewhere that relying on <code>viewAttached</code> wasn't a good solution. I'm also not sure if there is potential for a race condition since I'm allowing the activate to proceed.</p> <p>Any other recommendations?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload