10

Angular 2 では@CanActivate、コンポーネントをアクティブにするかどうかを決定できるコンポーネントの注釈を指定できます。インターフェイスではない理由は、コンポーネントがインスタンス化される前にコールバックが呼び出されるためです。問題は、そのコールバックに依存関係を注入する方法がわからないことです。また、特定のコンポーネントへのルーティングが許可されているかどうかを判断するために、ログインしているかどうか (および誰としてログインしているか) を通知するサービスが必要です。

@CanActivate コールバックに依存関係を挿入するにはどうすればよいですか? 私はES5を使用していますが、これは機能しません:

app.ListsComponent = ng.router.CanActivate([
    app.SessionService,
    function(session, instruction) {
        console.log(session);
        return true;
    }
])(app.ListsComponent);

編集: または、routerOnActivateコンポーネントでライフサイクル イベントを使用this.router.navigateし、そこにいるはずのないユーザーを遠ざけるために使用することもできます。欠点は、ブラウザーの履歴が壊れることです。特定の URL に到達するたびに非同期でリダイレクトすると、ブラウザーの [戻る] ボタンをあまり便利に使用できなくなります。このような状況の代わりにrouter.navigate使用する方法はありますか?history.replaceStatehistory.pushState

4

5 に答える 5

7

ここでのほとんどのソリューションは、新しいインジェクターを作成するため、階層内の他の場所からサブ依存関係をロードする際に問題を引き起こします。また、これにより追加の (非共有) サービスがインスタンス化されます。https://github.com/angular/angular/issues/4112でブランドンが提供するパターンに従うことをお勧めします

彼はこのプランクを参照しています: http://plnkr.co/edit/SF8gsYN1SvmUbkosHjqQ?p=preview

その主なアイデアは、アプリの初期化時に保存するシングルトン インジェクターです。これにより、すでに構成されているルート依存関係へのアクセスが提供され、さらに、おそらく意図されているように、サービスをシングルトンとして共有できるようになります。

import {Injector} from 'angular2/angular2';
let appInjectorRef: Injector;

export const appInjector = (injector?: Injector):Injector => {
    if (injector) {
      appInjectorRef = injector;
    }

    return appInjectorRef;
};

bootstrap([ServiceYouNeed]).then((appRef) => {
    // store a reference to the injector
    appInjector(appRef.injector);
});
于 2016-01-22T08:48:07.443 に答える
2

インジェクターを使用して注入する必要があります。私がやっているプロジェクトからの簡単なコピーペースト:

@CanActivate((next: ComponentInstruction, prev: ComponentInstruction) => {

  console.info('CanActivate hook! - can return boolean or Promise');

  var injector = Injector.resolveAndCreate([HTTP_PROVIDERS, YourService]);
  var yourService = injector.get(YourService);
  // do something with yourService
  return new Promise(function(resolve, reject) {
      resolve(true);
  });

})

たとえば、サービスがコンストラクターに HTTP サービスを注入する場合は、HTTP_PROVIDERS を渡す必要があります。

次のオブジェクトのパラメーターにオブザーバブルを配置するために使用します。次のオブジェクトは、次の「コンポーネント/状態」です。

@CanActivate((next: ComponentInstruction, prev: ComponentInstruction) => {

  console.info('properties component CanActivate hook! - can return boolean or Promise');
  var injector = Injector.resolveAndCreate([HTTP_PROVIDERS, PropertiesService]);
  var propertiesService = injector.get(PropertiesService);
  return new Promise(function(resolve, reject) {
      next.params['properties'] = propertiesService.getProperties();
      resolve(true);
  });

})

PropertiesService はバックエンドを呼び出し、プロパティを持つデータを表す Observable を返します

于 2016-01-12T10:31:48.970 に答える
1

ここ ( https://gist.github.com/clemcke/c5902028a1b0934b03d9 ) は、@shannon が参照する addInjector() ソリューションをテストする方法です。

beforeEachProviders(()=>[PERSON_SERVICE_PROVIDERS]);

beforeEach(inject([PersonService],()=>{
  let injector = Injector.resolveAndCreate([PERSON_SERVICE_PROVIDERS]);
  appInjector(injector);
}));
于 2016-01-26T21:25:08.280 に答える
1

それが最善の方法かどうかはわかりませんが、これらの人は独自の方法を拡張して使用し、メソッド<router-outlet>をオーバーライドすることでそれを行いますCanActivate:

https://auth0.com/blog/2015/05/14/creating-your-first-real-world-angular-2-app-from-authentication-to-calling-an-api-and-everything-in-の間に/

代わりに使用することもできますrouterOnActivate

https://angular.io/docs/js/latest/api/router/OnActivate-interface.html これがお役に立てば幸いです。

于 2016-01-10T23:42:33.090 に答える