Angular observable 处理多个订阅者
Angular observable handling multiple subscribers
在我的组件的ngOnInit中,ComProductService首先会获取产品类别并处理第三级类别并存储到服务中的proCatThird中。然后在我的 fillFormValues() 方法中,我需要从 ComProductService 获取 proCatThird 值。但是,从 proCatThird 返回的值是未定义的。是否有任何适当的方法可以将价值从一个订阅者传递给另一个订阅者?
ComProductService.service.ts
export class ComProductService {
baseUrl = environment.apiUrl + 'comProducts/';
proCatThird: ProCatThird[];
constructor(private http: HttpClient,
private authService: AuthService,
private errorHandler: ErrorService) { }
getProductCategories(): Observable<ProCatFirst[]> {
return this.http
.get(this.baseUrl)
.pipe(
map((response: ProCatFirst[]) => {
if (response) {
this.proCatThird = [];
response.forEach((first) => {
first.proCatSeconds.forEach((second) => {
second.proCatThirds.forEach((third) => {
this.proCatThird.push(third);
});
});
});
return response;
}
})
);
}
component.ts
constructor(
private activatedRoute: ActivatedRoute,
private comProductService: ComProductService,
) { }
ngOnInit() {
this.comProductService.getProductCategories().subscribe((response) => {
this.proCatFirst = response;
});
this.fillFormValues();
}
fillFormValues() {
this.activatedRoute.data.subscribe(data => {
this.product = data['product'];
this.productForm.patchValue({
name: this.product.name,
category: this.product.category,
});
const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
});
}
现在代码的问题是 fillForm 是在没有等待服务器响应的情况下启动的,并且 proCatThird
属性 没有填充所需的响应。
请在您的组件中执行此操作:
constructor(
private activatedRoute: ActivatedRoute,
private comProductService: ComProductService,
) { }
ngOnInit() {
this.comProductService.getProductCategories().subscribe((response) => {
this.proCatFirst = response;
this.fillFormValues(); // fill form values when the data has been received from server
});
}
fillFormValues() {
this.activatedRoute.data.subscribe(data => {
this.product = data['product'];
this.productForm.patchValue({
name: this.product.name,
category: this.product.category,
});
const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
});
}
编辑:在订阅中订阅的建议
ngOnInit() {
this.comProductService.getProductCategories()
.pipe(
mergeMap((response) => {
this.proCatFirst = response;
been received from server
return this.activatedRoute.data;
})
)
.subscribe(data => {
this.product = data['product'];
this.productForm.patchValue({
name: this.product.name,
category: this.product.category,
});
const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
});
}
这样,您将只有一个在页面加载时触发的订阅(组件初始化);
在我的组件的ngOnInit中,ComProductService首先会获取产品类别并处理第三级类别并存储到服务中的proCatThird中。然后在我的 fillFormValues() 方法中,我需要从 ComProductService 获取 proCatThird 值。但是,从 proCatThird 返回的值是未定义的。是否有任何适当的方法可以将价值从一个订阅者传递给另一个订阅者?
ComProductService.service.ts
export class ComProductService {
baseUrl = environment.apiUrl + 'comProducts/';
proCatThird: ProCatThird[];
constructor(private http: HttpClient,
private authService: AuthService,
private errorHandler: ErrorService) { }
getProductCategories(): Observable<ProCatFirst[]> {
return this.http
.get(this.baseUrl)
.pipe(
map((response: ProCatFirst[]) => {
if (response) {
this.proCatThird = [];
response.forEach((first) => {
first.proCatSeconds.forEach((second) => {
second.proCatThirds.forEach((third) => {
this.proCatThird.push(third);
});
});
});
return response;
}
})
);
}
component.ts
constructor(
private activatedRoute: ActivatedRoute,
private comProductService: ComProductService,
) { }
ngOnInit() {
this.comProductService.getProductCategories().subscribe((response) => {
this.proCatFirst = response;
});
this.fillFormValues();
}
fillFormValues() {
this.activatedRoute.data.subscribe(data => {
this.product = data['product'];
this.productForm.patchValue({
name: this.product.name,
category: this.product.category,
});
const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
});
}
现在代码的问题是 fillForm 是在没有等待服务器响应的情况下启动的,并且 proCatThird
属性 没有填充所需的响应。
请在您的组件中执行此操作:
constructor(
private activatedRoute: ActivatedRoute,
private comProductService: ComProductService,
) { }
ngOnInit() {
this.comProductService.getProductCategories().subscribe((response) => {
this.proCatFirst = response;
this.fillFormValues(); // fill form values when the data has been received from server
});
}
fillFormValues() {
this.activatedRoute.data.subscribe(data => {
this.product = data['product'];
this.productForm.patchValue({
name: this.product.name,
category: this.product.category,
});
const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
});
}
编辑:在订阅中订阅的建议
ngOnInit() {
this.comProductService.getProductCategories()
.pipe(
mergeMap((response) => {
this.proCatFirst = response;
been received from server
return this.activatedRoute.data;
})
)
.subscribe(data => {
this.product = data['product'];
this.productForm.patchValue({
name: this.product.name,
category: this.product.category,
});
const catName = this.comProductService.proCatThird.find(pct => pct.id === this.product.category).name;
});
}
这样,您将只有一个在页面加载时触发的订阅(组件初始化);