Ember.js: ルーターサービスをEmberRouterに注入すると、無限に再帰します

作成日 2019年03月22日  ·  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

PS routerEmberRouter挿入することもできません。

Bug Has Reproduction Router Bugs

最も参考になるコメント

記録のために@ursqontis 、ルーター内からルーターイベントを聞くことができます。 this.on('routeDidChange')を実行する必要があります。 このスニペットには実際の例があります: https

全てのコメント8件

不和に関する私たちの議論によると、ルーターの注入は機能しますが、 this._super(...arguments);呼び出す必要がありますhttps://github.com/efx/emberjs-17791/commit/8d8dd5afa1b9841742d1127a95689ab98c085632#diff -f3a289058604b2b069d07bb8e2cda60cR8
私のエラー; これを、ルーターインスタンスからルーティングイベントを登録できるようにすることと混同しました。

@efxそのコードスニペットはルーターサービスを注入していません、それは別の状況だと思います!

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

この非推奨の警告が表示されたため、 router.js 「didTransition」関数を「routeDidChange」イベントをリッスンすることで置き換えたいと思いました。

非推奨:非推奨の「didTransition」メソッドをオーバーライドしようとしました。 ルーターサービスを挿入し、「routeDidChange」イベントをリッスンしてください。 [非推奨ID:deprecate-router-events]詳細については、 https: //emberjs.com/deprecations/v3.x#toc_deprecate-router-eventsを参照してください。

記録のために@ursqontis 、ルーター内からルーターイベントを聞くことができます。 this.on('routeDidChange')を実行する必要があります。 このスニペットには実際の例があります: https

これがEmberRouterでこれを行うためのパブリックAPIであることが意図されている場合、それを文書化できますか? cc。 @pzuraq @rwjblue @chadhietala? パブリックAPIでない場合作成できます。

サービスインジェクションが失敗した場合、一般的にはバグと見なされるべきだと思います。 この場合の問題は、ルーターサービス自体がrouter:mainを挿入することです。

ここで起こっていることは次のとおりです。

  • インスタンス化されたときにservice:routerがrouter:mainを受信するようにするインジェクション
  • router:mainが検索されます
  • router:mainはインスタンス化時にservice:routerを検索します(これはすべてのサービスインジェクションのデバッグビルドで行われるため、参照されているサービスがシステムで利用できない場合に適切なエラーを提供できます。エラーが発生した場合のみではなく、サービスの使用を試みるため)
  • service:routerをインスタンス化するために、コンテナーはrouter:mainの作成を試み
  • ループ

ここでの修正は、ルーターサービスがrouter:main ...を熱心に検索しないようにすること

@rwjblue 、リフトはどれくらい難しいですか? 道がはっきりしていれば、おそらくこれにぶつかる可能性がある次の数週間で少し時間がかかるでしょう!

申し訳ありませんが、@ chriskrychoの時点でこれを見逃しました。 自動インジェクションを削除し、実際にプルされたときにのみルーターサービスを検索するのは、かなり簡単(たとえば、「それほど難しくない」)である必要があると思います。

このページは役に立ちましたか?
0 / 5 - 0 評価