Angular 11 数据未更改时未更新可观察到的路由器数据
Angular 11 Router data observable not updated when data has not changed
我有这个 Angular 解析器:
@Injectable()
export class DataResolver implements Resolve<any> {
constructor(private apiService: ApiService) {}
public resolve(route: ActivatedRouteSnapshot): any {
const data = {
param1: route.queryParamMap.get('param1'),
param2: route.queryParamMap.get('param2'),
};
return this.apiService.search(data);
}
}
apiService.search 方法如下所示:
public search(data): Observable<any> {
let params = new HttpParams();
for (const key in data) {
if (data.hasOwnProperty(key)) {
const value = data[key];
if (value) {
params = params.set(key, value);
}
}
}
return this.http.get<any>(`${API_URL}/endpoint`, { params });
}
然后我有一个组件可以订阅 ActivatedRoute
数据的变化:
route.data.subscribe((data) => {
console.log(data);
});
路线如下:
{
component: HomeComponent,
path: '/',
resolve: {
data: DataResolver,
},
runGuardsAndResolvers: 'paramsOrQueryParamsChange',
}
问题是,订阅处理程序只有在 data
实际发生变化时才会被调用,而不管解析器的 resolve
方法是否已被调用。特别是,如果两个(或更多)后续的 resolve 调用解析一个空数组,那么行 console.log(data)
只会在第一次被调用。
这是预期的行为吗?我可以强制 observable 发出新值吗?
我的目标是每次 resolve 解析一个空数组时都显示一条消息,无论它之前是否为空。
您不必要地将可观察对象包装在承诺中并解决了它。尝试像这样重写解析器。
@Injectable()
export class DataResolver implements Resolve<any> {
constructor(private apiService: ApiService) {}
public resolve(route: ActivatedRouteSnapshot): any {
const data = {
param1: route.queryParamMap.get("param1"),
param2: route.queryParamMap.get("param2"),
};
return this.apiService.search(data);
}
}
我还会考虑使用 HttpPrams
清理您的 API 服务
// import { HttpClient,HttpParams } from '@angular/common/http';
public search(data): Observable<any> {
let params = new HttpParams({ fromObject: data });
return this.http.get<any>(`${API_URL}/endpoint`, { params });
}
您可能需要将解析器添加到您的路由 table
RouterModule.forRoot([{
path: 'yourRoute',
component: YourComponent,
resolve: {
yourDataWillBeInThisProperty: DataResolver
}
}])
如果您想要重新加载组件,您可能需要更改路由器模块中的 onSameUrlNavigation
属性
@NgModule({
imports: [ RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' }) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
我不建议使用 onSameUrlNavigation
来解决你的问题,但我会订阅 route.queryParams
observable 并在那里触发搜索。
在你的组件中
ngOnInit(){
this.sub = this.route.queryParams.subscribe(() => { this.data = this.route.snapshot.data.data; });
// don't forget to unSubscribe
}
我有这个 Angular 解析器:
@Injectable()
export class DataResolver implements Resolve<any> {
constructor(private apiService: ApiService) {}
public resolve(route: ActivatedRouteSnapshot): any {
const data = {
param1: route.queryParamMap.get('param1'),
param2: route.queryParamMap.get('param2'),
};
return this.apiService.search(data);
}
}
apiService.search 方法如下所示:
public search(data): Observable<any> {
let params = new HttpParams();
for (const key in data) {
if (data.hasOwnProperty(key)) {
const value = data[key];
if (value) {
params = params.set(key, value);
}
}
}
return this.http.get<any>(`${API_URL}/endpoint`, { params });
}
然后我有一个组件可以订阅 ActivatedRoute
数据的变化:
route.data.subscribe((data) => {
console.log(data);
});
路线如下:
{
component: HomeComponent,
path: '/',
resolve: {
data: DataResolver,
},
runGuardsAndResolvers: 'paramsOrQueryParamsChange',
}
问题是,订阅处理程序只有在 data
实际发生变化时才会被调用,而不管解析器的 resolve
方法是否已被调用。特别是,如果两个(或更多)后续的 resolve 调用解析一个空数组,那么行 console.log(data)
只会在第一次被调用。
这是预期的行为吗?我可以强制 observable 发出新值吗?
我的目标是每次 resolve 解析一个空数组时都显示一条消息,无论它之前是否为空。
您不必要地将可观察对象包装在承诺中并解决了它。尝试像这样重写解析器。
@Injectable()
export class DataResolver implements Resolve<any> {
constructor(private apiService: ApiService) {}
public resolve(route: ActivatedRouteSnapshot): any {
const data = {
param1: route.queryParamMap.get("param1"),
param2: route.queryParamMap.get("param2"),
};
return this.apiService.search(data);
}
}
我还会考虑使用 HttpPrams
清理您的 API 服务// import { HttpClient,HttpParams } from '@angular/common/http';
public search(data): Observable<any> {
let params = new HttpParams({ fromObject: data });
return this.http.get<any>(`${API_URL}/endpoint`, { params });
}
您可能需要将解析器添加到您的路由 table
RouterModule.forRoot([{
path: 'yourRoute',
component: YourComponent,
resolve: {
yourDataWillBeInThisProperty: DataResolver
}
}])
如果您想要重新加载组件,您可能需要更改路由器模块中的 onSameUrlNavigation
属性
@NgModule({
imports: [ RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' }) ],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
我不建议使用 onSameUrlNavigation
来解决你的问题,但我会订阅 route.queryParams
observable 并在那里触发搜索。
在你的组件中
ngOnInit(){
this.sub = this.route.queryParams.subscribe(() => { this.data = this.route.snapshot.data.data; });
// don't forget to unSubscribe
}