J'essaie de travailler où le meilleur endroit pour exécuter une opération de charge à long terme utilise Durandalal.
De ce que je peux dire, la recommandation générale de chargement des données est dans le Cependant , exécutant une longue opération de charge en cours d'exécution dans la méthode CODE> Activer code> rend l'application "gel" pendant la fin de l'opération de charge. Par exemple, si ma charge était maintenant quelque chose comme ça? P> Dans ce scénario, l'URL est mise à jour pour refléter la page qui est chargée, mais le contenu de la page toujours Affiche la page précédente (qui est ce que je veux dire par "gèle"). p> Idéalement, ce serait bien si l'URL passe à la nouvelle page, et le contenu de la page doit également afficher la nouvelle page ( Même si les données de cette page n'ont pas encore été retournées). Ensuite, comme le retourne chaque opération de charge, la partie correspondante de la page doit être mise à jour lorsque les données sont liées au modèle de vue. P> est là une façon recommandée pour atteindre cet intérieur Durandal? Strong> p> Ma solution actuelle consiste à lancer la charge dans la méthode Activer méthode, qui est ce que je fais habituellement - quelque chose comme: p>
Activer CODE>, puis remplissez les données dans la méthode
Visite de la vue Code>: P>
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);
});
};
3 Réponses :
Quelle version de Durandal utilisez-vous? Dans Durandal 2.0.0pre, vous seriez autorisé à ne pas retourner une promesse dans Vous pourriez envisager de refactoring activer code> de sorte que la composition de la vue (sans données) pourrait se produire immédiatement. p>
mentionModel.one code> etc. dans un module qui renvoie une fonction de constructeur, de sorte que chacun, deux, trois serait responsable de la récupération de leurs propres données. De cette façon, vous auriez deux premiers appels n'auraient pas à attendre sur
LoadTellirddawhichThichsages Code>. Cela aurait un sens dans les scénarios où un, deux, trois ne dépendent pas fortement les uns des autres. P>
Le problème ici est que si un / deux / trois tous résolvez quelque part entre activate code> et
visiteux code>, vous vous retrouvez avec une condition de course qui enfreint vos reliures. Vérifiez le lien que j'ai mentionné dans ma question pour une explication de cela. Merci pour votre réponse cependant!
Vous n'avez pas à retourner une promesse, mais dans ce cas, vous devez gérer cela dans vos liaisons Knockout pour que vous ne liez pas si vous ne liez pas d'éléments indéfinis. Vous pouvez essayer de vous débarrasser de ce «retour» dans l'activation mais ajoutez une propriété indiquant si le modèle est toujours en cours de chargement. Quelque chose comme ceci: puis, à votre vue, vous pouvez avoir une section qui apparaît lorsque la vue est toujours en cours de chargement et que l'une apparaît lorsque le chargement est effectué. SORSTIHG - P> <div data-bind:"visible: isLoading()">Loading Data....</div>
<div data-bind:"visible: !isLoading()">Put your regular view with bindings here. Loading is done so bindings will work.</div>
Je ne suis pas sûr que cela empêche le problème des liaisons qui ne s'appliquent pas correctement cependant. Le visible:! Ischarger () code> n'empêche pas les liaisons d'enfants d'être appliquées (où, comme la liaison code> si code> fait parce que les nœuds enfants sont supprimés du DOM). D'après ce que j'ai vu, des problèmes se produisent si vous mettez à jour les observables de votre viewModel entre l'appel code> Appel et le
Avisatachied code> appel.
Lors de la lecture de ma question, il semble que je n'étais pas assez spécifique dans ce que je demandais - je voulais connaître la meilleure façon d'éviter les problèmes de liaison de données, plutôt que la meilleure façon d'afficher à l'utilisateur qu'une charge l'opération se passait. Alors maintenant, j'ai une meilleure compréhension de la nature de votre réponse; Je vais donc le marquer comme correct!
Super! Nous n'avons donc pas besoin de retourner la promesse envers le moteur.
pour référence; J'ai posté une question similaire sur le groupe Google Durandalal (demandant efficacement si l'utilisation de Activate et de la visionnement de cette manière est une idée OK) et a reçu cette réponse de Rob Eisenberg: P>
cela fonctionnera probablement. Le problème est que knockout va détruire Databindings sur des éléments si les propriétés sont mises à jour et l'élément n'est pas actuellement dans le document. Cela peut arriver en fonction de la chronométrage du code ASYNC. À cause de la manière dont la composition a travaillé dans 1.x, cela causerait des problèmes si vous ne retourniez pas la promesse de votre fonction Activate. Cela devrait fonctionner mieux en visiteux, mais En fonction de la nature de votre composition, la vue peut être attachée à son parent, mais toujours pas dans le document. Cela dépend de la profondeur de la composition. Donc, vous pourriez que vous puissiez rencontrer des problèmes avec cela aussi si Vous avez ceci dans un module profondément composé. Malheureusement, il n'y a pas Un moyen propre à ce sujet dans Durandalal 1.x en raison du comportement Knockout. Dans Durandal 2.x Nous avons une composition retravaillée afin que ce problème soit inexistant et renvoyant la promesse n'est plus nécessaire (bien que Vous pouvez toujours le faire). Durandal 2.0 sera libéré dans environ deux semaines. P> blockQuote>
En général, pour mes applications SPA, je crée un DIV transparent avec du texte "Chargement" et GIF. Cette div est superposée sur la page complète, de sorte que les utilisateurs reçoivent un retour à laquelle l'application tente de faire quelque chose, mais il ne faut pas pouvoir cliquer sur autre chose ou faire une sorte de manipulation de données alors que ma page est être navigué. Vous pouvez créer un service commun que n'importe quelle vue peut appeler avant que sa navigation ne commence et supprimer la DIV après la fin de la navigation.
Merci @yogesh, je fais quelque chose de similaire - bien que j'essaie d'éviter les superpositions de page complètes, car ils ne fonctionnent pas bien sur des appareils mobiles.