Angular.js: Prise en charge du module asynchrone.run()

Créé le 13 sept. 2013  ·  62Commentaires  ·  Source: angular/angular.js

Nous voulons émettre quelques appels $http dans le bloc d'exécution du module, idéalement, l'exécution ne devrait se terminer qu'après la fin du $http et du traitement avant la compilation du dom.

Lots of comments won't fix feature

Commentaire le plus utile

jfcfxekzl5m
Fonctionnalité simple mais trop difficile à mettre en œuvre. ??

Tous les 62 commentaires

Ce n'est pas si facile mais doit être examiné.

Pour ce faire, Jasmine définit un indicateur qui laissera la fonction s'exécuter et attendra le rappel jusqu'à ce que l'indicateur soit défini sur true , ou jusqu'à ce qu'un délai d'attente soit déclenché.

En gros quelque chose comme ça :

var flag = false;
$http(...).success(flag = true);
$timeout(function () {
    flag = true;
    // Or add some error handling stuff here
}, 5000);
while (!flag) {};

Ce n'est pas joli, mais devrait faire le travail. Le code ci-dessus n'est pas testé, vous devrez donc peut-être le modifier un peu. Il se fait tard ici. J'espère que quelque chose vous aidera jusqu'à ce que quelque chose d'un peu plus joli se présente.

+1

Sur une seconde cependant, cela conduit à l'impossibilité de dessiner un écran de chargement sophistiqué à l'aide de directives angulaires ...

+1

$routeProvider avec resolve résout-il pas ce problème ? Peut-être que je n'ai pas compris le problème...

C'est plus pour la prise en charge de l'initialisation du module asynchrone. Cela dit, je n'en ai plus besoin dans mes projets actuels.

@shahata $routeprovider fait cela, mais tous les cas d'utilisation des run s n'utilisent pas des routes. Dans mon cas d'utilisation, c'est pour un module qui enveloppe une directive et n'a rien à voir avec les routes.

+1

vérifie si la fonction run renvoie une promesse, puis ne procède que lorsqu'elle est résolue. puisque runBlocks est un tableau de fonctions, cela ne devrait pas être difficile du tout

+1

+1 embarrassant que cela ait été ignoré

une idée de quand ça va atterrir ? tellement frustrant de devoir déplacer des éléments d'initialisation à résoudre dans le routeur, principalement parce que parfois le code d'initialisation est indépendant de l'URL (c'est-à-dire qu'il doit être initialisé pour tout type d'URL que l'utilisateur arrive à votre SPA)

Je ne pense pas qu'angular bénéficiera désormais d'améliorations. ils sont tous ajoutés à angulaire 2.0

combien de temps la méthode run moitié cul restera synchrone ? c'est bien et compréhensible que config ne supporte pas les appels asynchrones, puisque vous n'avez aucun fournisseur qui fait des appels $http , mais run fait. regardez le type de hacks que l'absence de cette fonctionnalité (qui aurait dû être depuis le début) provoque
https://github.com/philippd/angular-deferred-bootstrap/blob/master/src/deferred-bootstrap.js

c'est gênant

+1

@btford examine comment les cas d'utilisation autour de cela pourraient être pris en charge via le nouveau routeur plutôt qu'à l'intérieur des blocs d'exécution.

+1

+1

+1

+1

Le principal problème que nous avons est que le $q est créé dans un module qui est chargé lorsque les runBlocks sont exécutés. Cela signifie que nous aurions besoin d'extraire "certains" des services (ou peut-être des modules) et de les créer d'abord, puis d'avoir une deuxième passe qui charge le reste des modules (et services, blocs d'exécution, etc.) après que $q a été créé.

@lgalfaso - peut-être pourriez-vous examiner cela un peu plus dans le cadre de votre travail $injector plus tard cette semaine (ou la prochaine) ?

Je sais que c'est juste une solution de contournement, mais j'ai normalement résolu le problème d'avoir une logique d'amorçage asynchrone en utilisant un routeur ui angulaire et en ayant un état abstrait racine en combinaison avec la résolution. L'état abstrait racine doit toujours être résolu en premier, c'est donc un bon endroit pour charger les paramètres, afficher les animations de chargement, etc.

Ce serait vraiment génial.
:+1:
En attente de ce correctif. J'espère qu'il sera en 1.4

+1

J'ai un autre cas d'utilisation : j'ai besoin d'initialiser mes points de terminaison simulés avec un appel $ http au démarrage (pour mettre en cache certaines données) ...

+1

+1

je viens de tomber dessus aussi...

@petebacondarwin, je pense qu'il serait

alternativement, $routeProvider pourrait offrir un paramètre de fonction configurable qui devrait différer le rendu de la route initiale.

+1

+1

Voici une solution de contournement possible : http://plnkr.co/edit/vi7mDjmD4NpZAoP7MVzr?p=preview
L'idée est qu'Angular vous donne en fait la possibilité de créer votre propre injecteur à partir d'un ensemble de modules. Dans ce cas, j'ai retardé la compilation du $rootElement jusqu'à ce qu'un tas de promesses ( resolves ) soient résolus. Il s'agit d'un POC et il y aurait un certain nombre d'autres cloches et sifflets qui seraient nécessaires pour préparer cette production. En dehors de toute autre chose, vous auriez besoin de détecter les erreurs dans les résolutions plutôt que de simplement les avaler.

+1

Il s'agit principalement d'un guide pour quiconque veut essayer ; Actuellement, le processus d'amorçage effectue les opérations suivantes :

  • Contrôles de santé
  • Crée le produit pour $rootElement
  • Crée l'injecteur
  • Compile et lie les $rootElement

De plus, lors de la création de l'injecteur, les étapes sont les suivantes :

  • Parcourir l'arborescence des modules de dépendances et

    • Initialisation du module qui enregistrerait les constantes, valeurs, fournisseurs et autres éléments du module

    • Exécuter les fonctions de configuration

    • Collectionnez les fonctions run pour plus tard

  • Exécutez toutes les fonctions run

Il y a quelques points clés :

  • Tous les blocs run sont exécutés avant la compilation de $rootElement
  • Il n'y a pas de cycles de condensé dans le processus de création de l'injecteur, le premier cycle de condensé a lieu lors de la compilation initiale de $rootElement
  • $q résout les promesses pendant un cycle de résumé _uniquement_

C'est:

  • S'il y a un module qui a une fonction run qui renvoie une promesse et que la promesse doit être résolue avant le démarrage de l'application, alors il y aura des cycles de résumé avant la compilation initiale (cela peut casser les applications existantes)
  • Un bloc de configuration ne peut pas retourner une promesse car une fonction config est injectée avec des fournisseurs, pas avec des instances

Quelle que soit la solution, doit gérer ces cas

+1
des nouvelles?
Je veux juste charger quelques paramètres de configuration avant que l'application ne démarre vraiment.

+1

Je chargerais des données asynchrones après le démarrage lorsque toutes mes usines sont opérationnelles et avant la compilation.

@dagingaa : Je pense que je choisirais votre solution comme solution de contournement ! Merci

  • 1

Mise à jour vers @dagingaa : la boucle for bloque mes navigateurs, c'est pas bon...

https://jsfiddle.net/tuxmachine/t4d63vnw/

C'est ainsi que je l'ai résolu pour une implémentation de jeton OAuth, qui nécessitait la résolution d'un appel ajax initial avant d'initialiser le reste de l'application.

Ne fonctionnera pas si vous avez plusieurs blocs d'exécution asynchrones cependant

+1

+1

+1

Cela fait deux ans que le problème a été ouvert et il n'y a toujours pas de bonne solution

@vladmiller Il existe des solutions mais peut-être que vous ne sentez pas qu'elles sont bonnes :

Mettre du travail d'application non trivial dans des blocs .run rend difficile le test unitaire de votre code. Ce n'est donc pas quelque chose que nous voulons encourager. Déplacer cela vers la glacière comme quelque chose que nous ne mettrons probablement pas en œuvre.

@petebacondarwin Je ne serais pas d'accord avec vous; tout le monde s'attend à ce que angluar soit simple et intuitif, à la place, vous devez soit implémenter votre propre module d'amorçage asynchrone, soit un module d'amorçage à un endroit différent. À mon avis, cela rend angulaire plus complexe.

Pouvez-vous également expliquer ce que vous entendez par dire que le code asynchrone dans .run rendra les tests plus difficiles ?

Toutes mes excuses pour mon précédent commentaire grossier.
Merci

@petebacondarwin Je ne vois pas en quoi cela rend le test difficile. si vous placez le code d'initialisation dans un service, vous pouvez simplement regarder/simuler/comparer les résultats que vous attendez de la maquette du backend http, qu'elle soit exécutée ou non dans .run bloc

Comment ça va?

La solution

Puisqu'il existe des solutions de contournement et que la prise en charge des blocs d'exécution asynchrones ajouterait de la complexité au bootstrap, je ne pense pas que nous mettrons en œuvre cette fonctionnalité.

jfcfxekzl5m
Fonctionnalité simple mais trop difficile à mettre en œuvre. ??

+1 pour cette fonctionnalité

+1

+1

La solution

+1. :(

+1

+1

+1

+1

Nous n'allons pas faire cela.

+100, tous les contournements sont terribles.

@Eduardo-Julio - nous n'allons pas implémenter cette fonctionnalité car cela rendrait le démarrage des applications AngularJS beaucoup plus complexe. L'ajout de + supplémentaires n'aidera pas.

Cette page vous a été utile?
0 / 5 - 0 notes