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

Angular, Share dynamic properties values between child components

我是 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() (并不总是有效),我可以在那里看到信息,但是是否没有其他更好的方法来在兄弟组件之间传递 属性 值?

出于某种原因,有时当我尝试编辑类别时(呈现反应式表单时)我会收到此错误(我认为与“lifecicle”有关:

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。相反,只需放置 router-outlet 和 Angular 即可根据当前 URL.

将您的子组件加载到插座中
<router-outlet></router-outlet>

也不需要设置“action”变量。由于当前操作由您的路线决定(如前所述,由 angular 处理)。

你的导航代码可以简单的变成。

this.router.navigateByUrl(`/service/update/${id}`);

请注意编辑路由的 :id 部分,将与您的 EditCategoryComponent 中的类别 ID 匹配。所以 id 成为 route/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;
        });
    }
}