问题描述
我是Angular的新手,我正在尝试学习最佳实践。我在这个问题上苦苦挣扎了两天,终于解决了,但是我对找到的解决方案不满意,我将尽力解释我的所作所为,也许有人知道更好的解决方案,在此先感谢。>
1我有3个组件:categoryComponente(父级)和3个子级(categoryCreate,categoryUpdate和categoryList)。
2 CategoriesList使用共享所有这些组件的服务(可以正常工作)呈现后端(端点)中的所有类别:
ngOnInit() {
this.service.getCategories().subscribe( (categories): any => {
this.categories = categories.data;
});
}
3 categoryList有一个(单击)事件:
<button (click)="editCategory(category._id)" class="btn btn-outline-primary btn-block">Update</button>
4 serviceList有一个editCategory方法,当用户单击按钮时,该方法将接收类别的ID。
editCategory( id: string ) {
// I pass the action name to show or hide the child component in the parent component html
// Example:
// <app-serviceupdate *ngIf="action === 'update'" [category]="['category']" [action]="action" // ></app-serviceupdate>
this.action = 'update';
for (let i = 0; i < this.categories.length; ++i) {
if (this.categories[i]._id === id) {
this.category = this.categories[i];
}
}
this.service.setCurrentCategory( this.category );
this.router.navigateByUrl(`/service/update`);
}
5现在,类别是共享服务组件(this.service.setCurrentCategory(this.category);)的属性,并且运行良好,当我运行更新表单时,如果调用this.service.getCurrentCategory()(并不总是能正常工作),但是是否没有其他更好的方法可以在同级组件之间传递属性值?
由于某些原因,有时当我尝试编辑类别时(呈现反应形式时),我会收到此错误(我认为这与“生命周期”有关:
categoryComponent.html:9 ERROR TypeError: Cannot read property 'name' of undefined
at categoryupdateComponent.buildForm (serviceupdate.component.ts:72)
at categoryupdateComponent.ngOnInit (serviceupdate.component.ts:39)
at checkAndUpdateDirectiveInline (core.js:31910)
at checkAndUpdateNodeInline (core.js:44367)
at checkAndUpdateNode (core.js:44306)
at debugCheckAndUpdateNode (core.js:45328)
at debugCheckDirectivesFn (core.js:45271)
非常感谢
解决方法
您的方法存在的问题是,如果用户刷新页面,则this.service.setCurrentCategory或当前“操作”设置的类别将丢失。
更好的方法是将路线定义为:
{ path: 'service',component: CategoryComponent,children: [
{ path:'update/:id',component: EditCategoryComponent }
{ path:'create',component: CreateCategoryComponent },{ path:'list',component: ListCategoriesComponent },]}
在这种情况下,您无需在父组件中引用模板HTML中的子组件。相反,只需放置一个路由器插座,Angular会根据当前URL来将您的子组件加载到插座中。
<router-outlet></router-outlet>
也无需设置“ action”变量。由于当前的动作是由您的路线决定的(如前所述,由路线决定)。
您的导航代码可以简单地变成
。this.router.navigateByUrl(`/service/update/${id}`);
请注意,编辑路线的:id部分将与您的EditCategoryComponent中的类别ID相匹配。因此,id成为路由/ URL的一部分。
export class EditCategoryComponent implements OnInit {
public category: Category;
constructor(
private readonly route: ActivatedRoute,private readonly service: CategoriesService,) {
}
ngOnInit() {
this.route.paramsMap.pipe(
switchMap((params) => this.service.getCategoryById(params.get('id')))
).subscribe((category) => {
this.category = category;
});
}
}