有角,在子组件之间共享动态属性值

问题描述

我是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;
        });
    }
}