web-dev-qa-db-ja.com

Reload Angular 4+同じURLパラメーターのルート

Angular 4+ルートをリロードする調査を行ってきましたが、代わりにコンポーネント内でURLパラメーターの変更をリッスンし、代わりにコンポーネントを再初期化することが望ましい方法のように見えます。

私が抱えている問題は、DRY(繰り返さないでください)アプローチを見つけようとすることです。 AngularJSこれはUIルーターで簡単でした。

ユースケース:

通知がクリックされると、関連するコンテンツに移動する必要があります-これは多くの異なるタイプのコンテンツである可能性があります。

例:_/posts/:id_または_/groups/:id_または_/users/:id_

ユーザーがすでにそのコンテンツを見ている場合、通知のメッセージを反映するためにリロードおよび更新されません。つまり、「John Doeがあなたの投稿にコメントした」(ユーザーがその投稿の古いバージョンを見ている可能性があります)または「Jane DoeがSome Groupへの参加要求を受け入れました」(ユーザーがそのグループのゲストビューを見ている可能性があります)。

ルートが同じであることを検出するときにwindow.location.reload()を使用することを検討しましたが、それは非常に望ましくない原因です(オーバーヘッドの再初期化、認証チェック、ソケット再接続など)。

どんな提案も大歓迎です!

9
Jamie Street

この場合、ルートは変更されず、パラメーターのみが変更されます。

この問題を解決するには、ActivatedRoute paramsにサブスクライブする必要があります。

export class MyClass implements OnInit {
   constructor(private activatedRoute: ActivatedRoute ) {
        this.activatedRoute.params.subscribe((params)=>{
          console.log('updatedParams', params);
        });
    }
}
1

ルートパラメータをサブスクライブして、変更するたびに変更を処理できるようにする必要があります。以下は私のプロジェクトのサンプルコードで、完全に正常に動作しています。

constructor(private router: Router) {
    this.route.params.subscribe(params => {
      this.initializePage(params['id']);
    });
}

initializePage(id:any){
//..Your code
// Consider this as your ngOnInIt() method and initialize everything here.
}

ここで、同じルートのURLでparam値が変更された場合、ページをリロードせず、すべてを再初期化するinitializePage(id)を呼び出しているときに値を変更します。

これがお役に立てば幸いです。

1
Vishw Patel

沿って this.router.url現在のページのURLを取得します。 queryParamesのようにルーターナビゲーションを使用するより。次は、ページネーションのページとしてqueryParamsを渡す例です。同様のアプローチを使用できます。

const url = this.router.url.split('?')[0]; // this will remove previous queryparms
    this.router.navigate([url], { queryParams: { page: $event } });

URLに何も変更がなければ、ルートを再ロードする方法はありません。実際、唯一のオプションはwindow.location.reload()であり、パラメーターの変更をリッスンしています。

2番目のオプションでは、クエリ文字列のid引数の変更を監視する汎用サービスを作成できます。 IdWatchServiceと呼びましょう。これは次のようになります。

@Injectable()
export class IdWatchService {
  constructor(private route: ActivatedRoute) {
  }

  get idChange(): Observable<number | undefined> {
    return this.route.queryParams.map(p => p['id'] as number | undefined).distinctUntilChanged();
  }
}

次に、このサービスを、変更に対応する必要があるコンポーネント(providersPostsComponentなど)のGroupsComponentのリストに追加できます。そして最後に、それらを同じコンポーネントに注入し、idChange observableにサブスクライブできます。

@Component({
  templateUrl: './posts.component.html',
  providers: [
    IdWatchService
  ]
})
export class PostsComponent {
  constructor(idWatchService: IdWatchService) {
    idWatchService.idChange.subscribe(id => {
      // Load data for the new ID and refresh the view
    });
  }
}
0
Pavlo Glazkov

私はangular 2.で同じシナリオ(非常によく似たユースケース)に直面しました。他の回答が言ったように、angularこれを実行します(フレームワークの仮定では、このような場合は、paramsの変更をリッスンするだけで解決されるはずです)。

あなたと同じように、コードを書き直したくなかったので、別のソリューションを使用しました。少しハックがかかっていましたが、変更する必要はほとんどありませんでした。

私が使用した解決策は、ページをリロードする必要がある同じレベルのhirearchyの下にダミーのルートを作成することでした。ダミーのルートでは、DummyComponentを使用しました。これは、次のルート(リロードしたいルート)が何であるかを記述するparamsデータをルートで受け取ります。言及しました)そして、私はそのルートに行くためにナビゲートメソッドで注入されたRounterクラスを使用しました。

このソリューションは、window.reloadを使用するよりもはるかに効率的で、非常に簡単に作成できると思います。 (そのコードにアクセスできないため、そのコード例をコピーすることはできません)

0
Ziv Glazer

私はDoCheckでこの問題を解決したヘッダーの通知セクションで同じ問題に直面していました

import { Component, DoCheck } from '@angular/core';

クラスでDoCheckインターフェイスを実装します

export class HeaderComponent implements DoCheck {

次に、ngDoCheck()メソッドを使用して、変数値が変更され、通知領域に同じ値が表示されるかどうかを確認します

ngDoCheck() {
    // check if values changes
}
0
sankey