Ember.js: L'injection du service de routeur dans EmberRouter se répète à l'infini

Créé le 22 mars 2019  ·  8Commentaires  ·  Source: emberjs/ember.js

Exemple de code:

// app/router.js
const Router = EmberRouter.extend({
  location: config.locationType,
  rootURL: config.rootURL,

  routerService: service('router'),

  init() {
    this.routerService.on('routeDidChange', () => {});
  }
});

Reproduction: https://github.com/ember-triage/emberjs-17791

PS Injecter router dans EmberRouter casse également.

Bug Has Reproduction Router Bugs

Commentaire le plus utile

@ursqontis pour mémoire, vous pouvez écouter les événements du routeur depuis le routeur. Vous devriez juste avoir besoin de faire this.on('routeDidChange') . Cet extrait de code a l'exemple de travail: https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8

Tous les 8 commentaires

Selon notre discussion sur la discorde, l'injection du routeur fonctionne mais vous devez invoquer this._super(...arguments);https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8
Mon erreur; associe cela à la garantie de pouvoir enregistrer les événements de routage à partir de l'instance de routeur.

@efx cet extrait de code n'injecte pas le service du routeur, je pense que c'est une situation différente!

Je peux également confirmer ce comportement, sur Ember 3.8

Code:

import EmberRouter from '@ember/routing/router';
import config from './config/environment';
import { set } from '@ember/object';

import { inject as service } from '@ember/service';


const Router = EmberRouter.extend({
  location: config.locationType,
  rootURL: config.rootURL,

  router: service(),
  routeHelpers: service(),

  init() {
    this._super(...arguments);
    this.router.on('routeDidChange', () => {
      // tracking with piwik, if the piwik object has been defined
      if (typeof _paq === 'object') {
        _paq.push(['trackPageView']);
      }

      // tracking with google analytics, if the ga method has been defined
      if (typeof ga === 'function') {
        return ga('send', 'pageview', {
          'page': this.get('url'),
          'title': this.get('url')
        });
      }

      // set current route to the onla accordion, which will open
      // it's corresponding accordion element
      var onlaController = this.routeHelpers.controllerFor('onla');
      set(onlaController, 'currentRouteName', this.router.currentRouteName);

    });
  }


});

Exception:

Exception has occurred: RangeError
RangeError: Maximum call stack size exceeded
    at Registry.isValidFullName (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:16657:20)
    at Registry.has (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:16448:17)
    at Registry.proto.validateInjections (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:16762:25)
    at processInjections (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:15999:28)
    at buildInjections (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:16040:7)
    at injectionsFor (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:16051:12)
    at FactoryManager.create (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:16116:13)
    at instantiateFactory (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:15979:63)
    at lookup (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:15907:12)
    at Container.lookup (https://n204.crealogix.net:4200/assets/vendor-e2a60dfe5e2603e2bdff789c3cdefd1e.js:15751:14)

Je voulais remplacer la fonction 'didTransition' dans mon router.js en écoutant l'événement 'routeDidChange', car j'ai reçu cet avertissement d'obsolescence:

DEPRECATION: Vous avez tenté de remplacer la méthode "didTransition" qui est obsolète. Veuillez injecter le service du routeur et écouter l'événement "routeDidChange". [id obsolète: deprecate-router-events] Voir https://emberjs.com/deprecations/v3.x#toc_deprecate -router-events pour plus de détails.

@ursqontis pour mémoire, vous pouvez écouter les événements du routeur depuis le routeur. Vous devriez juste avoir besoin de faire this.on('routeDidChange') . Cet extrait de code a l'exemple de travail: https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8

Si cela est destiné à être l'API publique pour faire cela dans EmberRouter , pouvons-nous le documenter? cc. @pzuraq @rwjblue @chadhietala? Si ce n'est pas une API publique, je suis heureux d'écrire un petit RFC pour en faire une API publique.

Je pense que cela devrait généralement être considéré comme un bogue si les injections de services échouent. Le problème dans ce cas est que le service du routeur lui-même reçoit router: main injecté dedans.

Ce qui se passe ici est:

  • une injection pour que service: router reçoive router: main lorsqu'il est instancié
  • routeur: le principal est recherché
  • router: main recherche service: router lors de l'instanciation (ceci est fait dans les builds de débogage pour toutes les injections de service, afin que nous puissions fournir une bonne erreur lorsqu'un service référencé n'est pas disponible dans le système. Par opposition à une erreur seulement _ si_ vous vous trouvez pour tenter d'utiliser le service)
  • afin d'instancier service: router le conteneur tente de créer router: main (pour satisfaire cette injection)
  • boucle

Le correctif ici est de faire en sorte que le service du routeur ne recherche pas avec empressement le routeur: main ...

@rwjblue , à quel point un ascenseur est-il difficile? Je vais avoir un peu de temps dans les prochaines semaines où je pourrais probablement frapper ceci si le chemin est libre!

Désolé d'avoir manqué ça à l'époque @chriskrycho. Je pense qu'il devrait être assez simple (par exemple "pas trop difficile") de supprimer l'auto-injection, et de rechercher uniquement le service du routeur lorsqu'il est réellement activé.

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