Ember.js: Внедрение сервиса маршрутизатора в EmberRouter бесконечно рекурсивно

Созданный на 22 мар. 2019  ·  8Комментарии  ·  Источник: emberjs/ember.js

Пример кода:

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

  routerService: service('router'),

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

Воспроизведение: https://github.com/ember-triage/emberjs-17791

PS Ввод router в EmberRouter тоже ломается.

Bug Has Reproduction Router Bugs

Самый полезный комментарий

@ursqontis для записи, вы можете прослушивать события маршрутизатора изнутри маршрутизатора. Вам просто нужно сделать this.on('routeDidChange') . В этом фрагменте есть рабочий пример: https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8

Все 8 Комментарий

Согласно нашему обсуждению разногласий, инъекция маршрутизатора работает, но вы должны вызвать this._super(...arguments);https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8
Моя ошибка; объединил это с гарантией того, что вы можете регистрировать события маршрутизации от экземпляра маршрутизатора.

@efx этот фрагмент кода не внедряет службу маршрутизатора, я считаю, что это другая ситуация!

Я также могу подтвердить это поведение на Ember 3.8

Код:

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

Я хотел заменить функцию didTransition в моем router.js , слушая событие routeDidChange, потому что я получил это предупреждение об устаревании:

УСТАРЕНИЕ: Вы попытались переопределить метод didTransition, который устарел. Внедрите службу маршрутизатора и прослушайте событие «routeDidChange». [устаревший идентификатор: deprecate-router-events] Подробнее см. https://emberjs.com/deprecations/v3.x#toc_deprecate -router-events.

@ursqontis для записи, вы можете прослушивать события маршрутизатора изнутри маршрутизатора. Вам просто нужно сделать this.on('routeDidChange') . В этом фрагменте есть рабочий пример: https://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8

Если это должен быть общедоступный API для этого в EmberRouter , можем ли мы это задокументировать? cc. @pzuraq @rwjblue @chadhietala? Если это не общедоступный API, я с радостью напишу небольшой RFC, чтобы сделать его общедоступным.

Я думаю, что обычно это следует рассматривать как ошибку, если сервисные инъекции терпят неудачу. Проблема в этом случае заключается в том, что сама служба маршрутизатора получает

Что здесь происходит:

  • инъекция, чтобы service: router получал router: main при его создании
  • router: main ищется
  • router: main ищет service: router при создании экземпляра (это делается в отладочных сборках для всех инъекций служб, чтобы мы могли выдать исправную ошибку, когда указанная служба недоступна в системе. В отличие от ошибки только _если_ вы попытаться воспользоваться услугой)
  • чтобы создать экземпляр service: router, контейнер пытается создать router: main (чтобы удовлетворить эту инъекцию)
  • петля

Исправление заключается в том, чтобы заставить службу маршрутизатора _не_ нетерпеливо искать маршрутизатор: main ...

@rwjblue , насколько это сложно? У меня будет немного времени в следующие несколько недель, когда я, вероятно, смогу достичь этого, если путь будет свободен!

Извините, я пропустил это в то время @chriskrycho. Я думаю, что должно быть довольно просто (например, «не слишком сложно») удалить авто-инъекцию и искать службу маршрутизатора только тогда, когда она действительно включена.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги