2016-08-08 6 views
16

私はAngular2の新人です。私はAngular 1ダイジェストサイクルに慣れています。つまり、ビューの範囲を更新すると、$scope.$digest()を呼び出してダイジェストを手動でトリガーすることができます。しかし、新しいフレームワークに古いバージョンの暗黙的なデータバインディングがないことを考えると、Angular2でこれを行う方法はわかりません。コンポーネントを手動で再レンダリングするにはどうすればよいですか?

ここに私の問題があります。

// Router 
export const AppRoutes : RouterConfig = [ 
    { 
    path: 'my/:arg/view', 
    component: MyComponent 
    } 
] 

は、その後、私はこのコンポーネントを持っている:

// Component 
export class MyComponent { 
    constructor(private route : ActivatedRoute, 
     private r : Router) { 
    let id = parseInt(this.route.params['value'].id); 
    console.log(id); 
    // do stuff with id 
    } 

    reloadWithNewId(id:number) { 
     this.r.navigateByUrl('my/' + id + '/view'); 
    } 
} 

私は/my/1/viewをURLに移動言うことができます私は、パラメータ付きのURLがヒットしたときに、コンポーネントをロードするルートを持っています。コンストラクターが呼び出され、番号1が記録されます。ただし、reloadWithNewIdに新しいID、reloadWithNewIf(2)をコールした場合、コンストラクターは再び呼び出されません。コンポーネントを手動で再ロードするにはどうすればよいですか?

+3

推奨される方法は、(ngOnInit()のparamsにサブスクライブする)受け入れられた解決策ですが、必ずしも機能するとは限りません。たとえば、x軸ラベルの変更に正しく応答しないng2-charts https://github.com/valor-software/ng2-chartsを使用しています(https://github.com/valor -software/ng2-charts/issues/547)を参照してください。サードパーティのコンポーネントにこのようなバグがある場合、文字通りそのコンポーネントをリロードする方法はありますか? –

答えて

15

コンポーネントをリロードする必要はありません。ただ、モデルとビューの更新自体を更新:

export class MyComponent { 
    constructor(private route : ActivatedRoute, 
     private r : Router) {} 

    reloadWithNewId(id:number) { 
     this.r.navigateByUrl('my/' + id + '/view'); 
    } 

    ngOnInit() { 
     this.sub = this.route.params.subscribe(params => { 
     this.paramsChanged(params['id']); 
     }); 
    } 

    paramsChanged(id) { 
     console.log(id); 
     // do stuff with id 

    } 
} 
+0

'ngOnInit'フックと@ madhu-ranjanのようなコンストラクタを使用する利点は何ですか? – dopatraman

+2

コンストラクタで 'this.route.params.subscribe(...)'を実行することもできます。'@Input()'はコンストラクタが実行されているときではなく、 'ngOnInit()'が実行されているときです(この実際の使用例では関係ありません)。 –

1

パラメータを更新するだけでは、コンストラクタは再度呼び出されません。 Componentクラスがすでにインスタンス化されているので、

あなたが変化を検出したい場合は、以下のようなのparamsの変更を購読することができ、

constructor(route: ActivatedRoute) { 
    route.params.subscribe(param => { 
     let id = param['id ']; 
     // Do your stuff with id change. 
    }); 
    } 

・ホープ、このことができます!

+0

コンストラクタの代わりに 'ngOnInit'フックを使うのはなぜですか? – dopatraman

+0

@dopatraman、ngOnInitは、コンポーネントが既に初期化されているため、reloadWithNewIdを起動してパラメータを更新するだけでは起動されません。ここには[Plunker](https://plnkr.co/edit/nnpRhYK9thLOth5uxbxD?p=preview)があります。 –

+0

私も問題に直面し、ngOnInit内のroute.params.subscribeを実装することは実際には動作しています:) – KCarnaille

6

あなたは戻って、あなたが望むものにし、いくつかの他のURLに移動してによって再初期化コンポーネントにangular2を強制することができます。

コンポーネントコンストラクタ:テンプレート(例)で

constructor(private router: Router) {} 

:そして

(click)="onTabChange(id)" 

コンポーネントクラス内の:ここ

ルータクラスのメソッドを使用して私の簡単な回避策(https://angular.io/docs/ts/latest/api/router/index/Router-class.html参照)です。

onTabChange() { 
    if (this.router.navigated === false) { 
    // Case when route was not used yet 
    this.router.navigateByUrl(`/module/${id}`); 
    } else { 
    // Case when route was used once or more 
    this.router.navigateByUrl(`/index`).then(
    () => { 
     this.router.navigateByUrl(`/module/${id}`); 
     }); 
    } 
} 
+0

あなたは私の人生を救った。 –

+0

ちょっとハッキリですが、それは質問に答える唯一の答えであり、リフレッシュよりはるかに効率的です。 –

+0

偽のURLを履歴から削除する方法がある場合にのみ、有効な解決策です。さもなければ、ブラウザの戻るボタンは期待されることをしません。 – benek

関連する問題