首页 > 解决方案 > 从 Angular 中的父组件更新子组件

问题描述

我一直在努力让它在 Angular 中工作。我有一个主机组件(父组件),它使用子组件来呈现下拉列表。列表的源是从父级传递的。因此,例如,如果父组件在源属性上传递 5 个项目,则子组件将为下拉列表呈现 5 个选项。

这是我调用子组件的代码的一部分:

父组件.html

<ng-container>
   <th mat-header-cell *matHeaderCellDef>
         <app-column-header
            [id]="column.id"
            [name]="column.name"
            [source]="myObject.options"
          ></app-column-header>
   </th>
</ng-container>

父组件.ts

export class ParentComponent  {  

@ViewChild(ChildComponent) ChildComponent;  

 // more code

  private updateChildSource() {
    this.child.updateDataSource(myObject.options);
  }
}

到目前为止,这工作正常。

现在,我面临的挑战是要传递的项目列表需要是动态的(myObject.options)。因此,例如,第一次让我们说我要传递 5 个项目。Angular 采用这 5 个项目并正确渲染子组件。但是,一旦子组件已经渲染并且如果我将源更改为 2 个项目而不是来自父级的 5 个并传递新源,则子组件不会渲染新项目 (2)。

child.component.ts

export class ColumnHeaderComponent implements OnInit, OnChanges {
  @Input() id: string;
  @Input() name: string;
  @Input() source: any[];

 childField: any;

  ngOnInit(): void {
    const options = this.doStuffHere(this.source);
    this.childField= {
      id: this.id,
      options,
    };
  }

  updateDataSource(newSource: Option[]): void {
     console.log(`print call from parent. old options: 
     ${JSON.stringify(this.childField.options)} - new options: ${JSON.stringify(newSource)}`);
     this.source= newSource;
     const options = this.doStuffHere(this.source);
     this.childField= {
       id: id,
       options,
     };
  }

  ngOnChanges(changes: SimpleChanges) {
    console.log('changed');     
    for (const propName in changes) {
      const chng = changes[propName];
      const cur  = JSON.stringify(chng.currentValue);
      const prev = JSON.stringify(chng.previousValue);
      console.log(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
    }
  }
}

如前所述,子组件正在接收原始项目和新项目,甚至 ngOnChanges 方法也在捕获它并正确打印值。但由于某种原因,我还不知道子组件仍在渲染旧项目 (5) 而不是新项目 (2)。

不确定,如果我在这里遗漏了什么?或者这个问题很清楚,足以说明我面临的问题。

你能指出我如何解决这个问题的正确方向吗?提前致谢。

标签: javascriptangular

解决方案


正如 Marek 所说,您可以直接将父组件中的列表作为子组件的输入传递。[list]="list" 表示法已经是反应式的。然后,您只需使用子组件下拉列表中的列表。

注意:这里没有用,但作为@Input,您可以设置函数而不是变量。每次输入值变化时都会触发。


推荐阅读