角度父级到数组中子级通信

时间:2018-08-02 02:31:46

标签: angular parent-child ngfor angular-components

我有一个由父级组件控制的动态表单,其中包含一系列使用ngFor呈现的子级DTO,这些子级组件将通过DTO传递并使用其自己的模板。像这样:

父HTML:

implementation 'com.android.support:design:27.1.1'

父项:

<div class="row parameter-list" *ngFor='let parameter of parameters'>
  <div class="col-md-12">
    <parameter-list-item
    [parameter]="parameter"
    [types]="types"
    [events]="eventsSubject.asObservable()"
    (onDelete)="onDeleteHandler($event)">
    </parameter-list-item>
  </div>
</div>

儿童HTML:

@Input()
parameters: Parameter[];

子组件:

<input type="text" [(ngModel)]="parameter.Name" [disabled]="readonly">
<input type="text" [(ngModel)]="parameter.Description" [disabled]="readonly">

DTO:

constructor() {
  this.readonly = true;
}

readonly: boolean;

@Input()
parameter: Parameter;

当我想更改列表时,通过向Parent组件添加一个参数,我将使用(单击)处理程序执行以下操作:

export class Parameter {
   Name: string,
   Description: string) { }
}

本质上让取消移位触发适当的生命周期挂钩,而不是。

我需要知道的是,是否可以通过某种方式与新创建的子组件进行通信,并将其只读布尔值设置为false。

2 个答案:

答案 0 :(得分:0)

许多种方式在父母与子女之间交流信息。

以下是一些: enter image description here

正如另一位发帖人所述,您可以使用@ViewChild来获取对子组件的引用并设置其属性。

另一个选择(如上所示)是使用[vc_column width=\"1/2\"]生命周期挂钩。您可以使用它来监视对任何Input属性的更改。因此,您可以监视Parameter的更改,并让子级根据该参数更改设置只读标志本身。

另一种选择是构建服务来管理标志,让父项设置标志值,子标志读取它。

对于更大或更复杂的应用,您可以考虑使用NgRx进行此通信。 NgRx是一个状态管理库,用于管理数据更改和通知。

希望这会有所帮助。

答案 1 :(得分:0)

我想出了一个不太坏的解决方案;我最终只是将父母中的数组分成2个:

  parametersToAdd: Parameter[];

  @Input()
  parameters: Parameter[];

然后我将父html更改为:

<div class="row parameter-list" *ngFor='let parameterToAdd of parametersToAdd'>
  <div class="col-md-12">
  <parameter-list-item
    [parameter]="parameterToAdd"
    [types]="types"
    [readonly]="false"
    (onDelete)="onDeleteHandler($event)"
  ></parameter-list-item>
  </div>
</div>

<div class="row parameter-list" *ngFor='let parameter of parameters'>
  <div class="col-md-12">
    <parameter-list-item
    [parameter]="parameter"
    [types]="types"
    [readonly]="true"
    (onDelete)="onDeleteHandler($event)"
    ></parameter-list-item>
  </div>
</div>

添加点击处理程序现在看起来像:

addParameter(): void {
  console.log("ParameterListComponent.addParameter()");
  let name = "Name" + this.parameters.length;

  let parameter = new Parameter(
    name,
    "Description",
    null,
    new Array(),
    new ParameterTypeInfo(ParameterDataType.Boolean, null, null, new 
    Array(),null, null));

  this.parametersToAdd.unshift(parameter);
}

基本上有2个集合,这些集合将在应用程序运行时呈现为外观相同。我之所以需要这样做,是因为我们的后端API不允许您编辑DTO中的所有字段,而只能编辑其中的一些字段。因此,对于页面加载时从后端API提取的现有记录,我需要子组件处于“只读”模式。相反,如果要添加新参数,则可以执行任何操作...因此,基本上现有记录不能对其进行太多更改,并且大多数字段都必须处于只读模式,因此可以写入任何新记录模式,直到您保存它们..然后它们就被发布了,页面应该随它们一起在只读集合中刷新。