Angular-7-Applicationでは、@ ngrxと@ngrx/router-storeを使用して、クエリパラメーターを状態にします。
アプリケーションのいくつかのコンポーネントは、ページ付けされたリストです。すべてのリストがコンポーネントとしてあり、Pagination-Componentがすべてのリストに含まれています。
現在のページはクエリパラメータとしてURLに保存されます:user/:userId/agent?page=0
そしてPaginationComponentはstate.router.state.queryParams.page
から現在のページを取得します。ただし、ユーザーがURL user/:userId/agent
にアクセスすると、queryParams.page
はundefinedを返します。
すべてのコンポーネントでstate.router.state.queryParams.page || 0
を使用することでこれを解決できますが、もっと簡単な方法があるかどうか疑問に思います-クエリパラメータのないルートをクエリパラメータのあるルートにリダイレクトできます?
最も明白なリダイレクトを使用してみました:
{ path: 'user/:userId/agent', redirectTo: '/user/:userId/agent?page=0', pathMatch: 'full' },
{ path: 'user/:userId/agent?page=0', component: AgentListComponent },
しかし、私はError: Cannot match any routes. URL Segment: 'user/max/agent'
を取得します。
私が見つけた唯一の機能要求は これ 上記のエラーが表示される場所でした。
特にあなたの質問のために:
クエリパラメータのないルートをクエリパラメータのあるルートにリダイレクトできますか?
私はこれがうまくいくとは思わないので?クエリにはセパレータがあり、URLのクエリ文字列の一部ではありません。
代替1-ngrxを使用しているため、これを行う1つの方法は、カスタムシリアライザーを使用することです。 ngrx.ioサイトのドキュメント シリアル化を使用してパラメーターを返す例を示します。これは、パラメータが存在しない場合にデフォルトをパラメータに追加するロジックを追加できる場所です。これは各ルートで発生するため、あまり理想的ではない可能性がありますが、ルートが単純になる可能性があることは否認します。
import { Params, RouterStateSnapshot } from '@angular/router';
import { RouterStateSerializer } from '@ngrx/router-store';
export interface RouterStateUrl {
url: string;
params: Params;
queryParams: Params;
}
export class CustomSerializer implements RouterStateSerializer<RouterStateUrl> {
serialize(routerState: RouterStateSnapshot): RouterStateUrl {
let route = routerState.root;
while (route.firstChild) {
route = route.firstChild;
}
const {
url,
root: { queryParams },
} = routerState;
const { params } = route;
// Add here
if (<insert url logic> && queryParams.page === undefined) {
queryParams.page = 0;
}
// Only return an object including the URL, params and query params
// instead of the entire snapshot
return { url, params, queryParams };
}
}
代替2-HttpClientをラップするか、より好ましくは、これをチェックし、存在しない場合はリクエストに追加する汎用ページリストメソッドを作成できますページ。 この回答 は、パラメータの追加を実現する方法の例を示しています。
代替3-ページをパスの一部として使用し、必要に応じて回避策/変更を行ってリクエストを生成できます。
{ path: 'user/:userId/agent', redirectTo: '/user/:userId/agent/0', pathMatch: 'full' },
{ path: 'user/:userId/agent/:page', component: AgentListComponent },
Angular-7-Applicationでは、@ ngrxと@ngrx/router-storeを使用して、クエリパラメーターを状態にします。
クエリパラメータと状態を同期させるには、アプリケーションのページ変更をもたらすアクションをキャプチャするエフェクトが必要です。イベント内には、次のようなものがあります。
@Effect({dispatch:false})
setRouteParams = this.actions$.pipe(
ofType<ActionCausingPageChange>("action name"),
tap( action =>{
let a = { page: action.payload.page };
// or in case it's not part of action payload, get it from store
this.router.navigate(
[], {
relativeTo: this.route,
queryParamsHandling: 'merge',
queryParams: a
});
}
)
);
次に、ページのリロード時にクエリパラメータから状態を更新するメタレデューサーを用意します。
export function initStateFromQueryParams(
reducer: ActionReducer<AppState>
): ActionReducer<AppState> {
return function(state, action) {
const newState = reducer(state, action);
if ([INIT.toString(), UPDATE.toString()].includes(action.type)) {
const urlParams = new URLSearchParams(window.location.search);
return { ...newState, page: urlParams.get("page") };
}
return newState;
};
}
このようにして、ページ番号が変更されたかどうかを常に知ることができ、その結果、URLに反映されます。したがって、そのルートが初期データを取得した後に新しいルート(コンポーネント)に移動した場合でも、エフェクトがトリガーされ、クエリパラメーターが更新されます。
この驚異的な 記事 angular apps)の状態管理についてチェックアウトすることをお勧めします
私にとって、これはルートパスで機能しました:
{
path: '',
redirectTo: '/foo?bar=baz',
pathMatch: 'full'
}
ただし、名前付きパラメーター(:userId
など)で同じことを試みると、機能しません。