Ember.js: Das Injizieren des Router-Dienstes in EmberRouter ist unendlich rekursiv

Erstellt am 22. März 2019  ·  8Kommentare  ·  Quelle: emberjs/ember.js

Codebeispiel:

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

  routerService: service('router'),

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

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

PS Das Injizieren von router in EmberRouter bricht ebenfalls ab.

Bug Has Reproduction Router Bugs

Hilfreichster Kommentar

@ursqontis für den Datensatz können Sie die Router-Ereignisse vom Router aus abhören. Sie sollten nur this.on('routeDidChange') tun müssen. Dieses Snippet enthält das Arbeitsbeispiel: https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8

Alle 8 Kommentare

Gemäß unserer Diskussion über Zwietracht funktioniert das Injizieren des Routers, aber Sie müssen this._super(...arguments); aufrufenhttps://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8
Mein Fehler; Dies wurde mit der Sicherstellung kombiniert, dass Sie Routing-Ereignisse von der Router-Instanz aus registrieren können.

@efx das Code-Snippet injiziert nicht den Router-Dienst, ich glaube, das ist eine andere Situation!

Ich kann dieses Verhalten auch in Ember 3.8 bestätigen

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);

    });
  }


});

Ausnahme:

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)

Ich wollte die Funktion 'didTransition' in meinem router.js ersetzen, indem ich das Ereignis 'routeDidChange' abhörte, da ich die folgende Warnung erhielt:

DEPRECATION: Sie haben versucht, die veraltete Methode "didTransition" zu überschreiben. Bitte fügen Sie den Router-Dienst ein und hören Sie sich das Ereignis "routeDidChange" an. [Verfalls-ID: Veraltete Router-Ereignisse] Weitere Informationen finden Sie unter https://emberjs.com/deprecations/v3.x#toc_deprecate -router-events.

@ursqontis für den Datensatz können Sie die Router-Ereignisse vom Router aus abhören. Sie sollten nur this.on('routeDidChange') tun müssen. Dieses Snippet enthält das Arbeitsbeispiel: https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8

Wenn dies die öffentliche API dafür sein soll, können wir dies in EmberRouter dokumentieren? cc. @pzuraq @rwjblue @chadhietala? Wenn es sich nicht um eine öffentliche API handelt, schreibe ich gerne einen kleinen RFC, um ihn zur öffentlichen API zu

Ich denke, es sollte allgemein als Fehler angesehen werden, wenn Service-Injektionen fehlschlagen. Das Problem in diesem Fall ist, dass der Router-Dienst selbst Router: Main erhält.

Was hier passiert ist:

  • eine Injektion, damit service: router router: main empfängt, wenn es instanziiert wird
  • Router: Haupt wird nachgeschlagen
  • router: main sucht nach service: router bei der Instanziierung (dies erfolgt in Debug-Builds für alle Service-Injektionen, damit wir einen guten Fehler liefern können, wenn ein referenzierter Service nicht im System verfügbar ist. Im Gegensatz dazu, dass nur Fehler auftreten, wenn Sie auftreten um zu versuchen, den Dienst zu nutzen)
  • Um Service: Router zu instanziieren, versucht der Container, Router: Main zu erstellen (um diese Injektion zu erfüllen).
  • Schleife

Die Lösung hier besteht darin, dass der Router-Dienst den Router nicht eifrig nachschlägt : main ...

@rwjblue , wie schwer ist ein Aufzug? Ich werde in den nächsten Wochen ein wenig Zeit haben, wenn ich das wahrscheinlich treffen könnte, wenn der Weg frei ist!

Entschuldigung, ich habe das damals @chriskrycho verpasst. Ich denke, es sollte ziemlich einfach sein (z. B. "nicht zu schwer"), die automatische Injektion zu entfernen und den Router-Service nur dann nachzuschlagen, wenn er tatsächlich aktiviert ist.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen