web-dev-qa-db-ja.com

angle4で異なるルートパラメータを使用してコンポーネントをリロードします

私はangular2ルーティングを使用しています。ユーザーが検索フィールドに値を再入力して検索をクリックすると、同じコンポーネントを再ロードする必要がありますが、ルートパラメータが異なります。

<button (click)="onReload()">Search</button>

onReload() {
this.router.navigate(['results',this.location]);
}

これは私のResultsComponentのルートパスです

{ path:'results/:location', component:ResultsComponent}

この関数はURLを変更しますが、コンポーネントを再初期化しません。

Anglejs、ui-routerではこのように実現できました。

$state.go($state.current, location, {reload: true});

これをangular4で行うにはどうすればよいですか?

8
CKA

Route.params監視可能ストリームのサブスクリプションコールバック関数内のサブスクリプションコールバック関数内で初期化ロジックを実行する必要があります。

コンポーネントクラス内

@Component({
  ...
})
export class MyComponent implements OnInit {

   myLocation:string;

   constructor(private route:ActivatedRoute) {}

   ngOnInit() {
     this.route.params.subscribe((params:Params) => {
        this.myLocation = params['location'];
        // -- Initialization code -- 
        this.doMyCustomInitialization();
     }
   }

   private doMyCustomInitialization() {
       console.log(`Reinitializing with new location value ${this.location}`);
   }
}

別の注意点として、「location」の値に基づいてデータを解決する必要がある場合は、コンポーネントが作成される前にデータを解決する解決ガードを使用する必要があります。リゾルブガードとルーティングの詳細については、 https://angular.io/guide/router#resolve-guard を参照してください。

これが実用的なプランカーです。 https://plnkr.co/edit/g2tCnJ?p=preview

4
JeanPaul A.

編集済み

angularこれを行うようにルーターに指示する方法は onSameUrlNavigation as angular 5.1

しかし、私はこの問題を別の方法で解決する必要がありました( Stackblitz )、subscribingからroute eventsに、実際にcustom reInit methodを呼び出します。

秘訣は、すべてのサブスクリプションを同じオブジェクトに追加し、ngOnDestroyがangularによって呼び出された場合にのみサブスクリプションを解除し、残りのテンプレート変数をcustom destroy method ..から変更することです。

    public subscribers: any = {};

    constructor(private router: Router) {
    /** 
      * This is important: Since this screen can be accessed from two menu options 
      * we need to tell angular to reload the component when this happens.
      * It is important to filter the router events since router will emit many events,
      * therefore calling reInitComponent many times wich we do not want.
      */   
      this.subscribers._router_subscription = this.router.events.filter(evt => evt instanceof NavigationEnd).subscribe((value) => { 
        this.reInitComponent();
      });
    }

    reInitComponent() {
        this.customOnDestroy();
        this.customOnInit();
    }

    customOnInit() {
        // add your subscriptions to subscribers.WHATEVERSUB here
        // put your ngOnInit code here, and remove implementation and import 
    }

    customOnDestroy() {
      // here goes all logic to re initialize || modify the component vars  
    }

    /**
     * onDestroy will be called when router changes component, but not when changin parameters ;)
     * it is importatn to unsubscribe here
     */
     ngOnDestroy() {  
       for (let subscriberKey in this.subscribers) {
          let subscriber = this.subscribers[subscriberKey];
          if (subscriber instanceof Subscription) {
            subscriber.unsubscribe();
          }
        }
     }

LifecylceフックngOnInitを実装する場合は、それを削除して、例のようにカスタムメソッドを実装する必要があることに注意してください。

this angular bug。Angularは、実際にはrouter.eventsから自動的に登録解除する必要があるため、unsubscriptionメソッドを追加しましたコンポーネントを破棄するときですが、そうではないため、手動でサブスクライブを解除しないと、コンポーネントを入力した回数だけhttpリクエスト(たとえば)を呼び出すことになります。

3
Lucas

https://angular-2-training-book.rangle.io/handout/routing/routeparams.html

コンポーネントで、パラメータが変更されたかどうかを検出するために、パラメータをサブスクライブする必要があります。

2
Justin