Sto cercando di capire dove si trova il posto migliore per eseguire un'operazione di carico di lunga durata utilizzando Durandal.Operazioni di carico a lungo termine in durezza
Da quello che posso dire, la raccomandazione generale per il caricamento dei dati è nel metodo activate
del ViewModel, che è quello che faccio di solito - qualcosa come:
viewModel.activate = function() {
var loadPromise = myService.loadData();
return $.when(loadPromise).then(function (loadedData) {
viewModel.data(data);
});
};
So che se non restituire il promettono qui, quindi di solito ci sono problemi con i binding - come this question and answer indicates.
Tuttavia, l'esecuzione di un'operazione con carico prolungato nel metodo activate
rende l'app "bloccata" mentre l'operazione di caricamento è completata. Ad esempio, cosa succede se il mio carico era ora qualcosa di simile?
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);
});
};
In questo scenario, l'URL viene aggiornato per riflettere pagina che viene caricata, ma il contenuto della pagina mostra ancora la pagina precedente (che è quello che intendo per "congela").
Idealmente, sarebbe bene se l'URL dovesse cambiare alla nuova pagina, e il contenuto della pagina dovrebbe mostrare anche la nuova pagina (anche se i dati per quella pagina non sono ancora stati restituiti). Quindi, al ripristino di ciascuna operazione di caricamento, la parte pertinente della pagina deve essere aggiornata quando i dati sono associati al modello di visualizzazione.
Esiste un modo consigliato per ottenere questo all'interno di Durandal?
La mia soluzione attuale è quella di kick-off il carico nel metodo activate
, e quindi popolare i dati nel metodo 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);
});
};
E sembra a lavorare, ma mi ricordo di aver letto da qualche parte che affidarsi a viewAttached
non era una buona soluzione. Inoltre, non sono sicuro che ci sia un potenziale per una condizione di gara dal momento che sto permettendo che l'attivazione proceda.
Altri consigli?
In generale, per le mie applicazioni SPA creo un div trasparente con "caricamento" di testo e gif. Questo div è sovrapposto alla pagina completa, in modo che gli utenti ricevano un feed back che l'applicazione sta cercando di fare qualcosa ma allo stesso tempo non dovrebbero essere in grado di fare clic su qualcos'altro o fare una sorta di manipolazione dei dati mentre la mia pagina è essere navigato. È possibile creare un servizio comune che qualsiasi vista può chiamare prima dell'avvio della navigazione e rimuovere il div dopo la fine della navigazione. – Yogesh
Grazie a @ Yogesh, faccio qualcosa di simile, anche se cerco di evitare gli overlay di pagina completi perché non si comportano bene sui dispositivi mobili. – gerrod