Angular 2 - 通过引用传递 object 字段。可重复使用的方式来编辑 objects

Angular 2 - pass an object field by reference. Reusable way to edit objects

我正在创建可重复使用的 table 组件,它将允许编辑 objects 字段以准备将它们发送到 API。

object:

person: {
  name: "John"
  job: {
    type: "IT"
    title: "Software Engineer"
  }
}

我想将 object 嵌套字段传递给组件并进行编辑。 F.e:

<edit-field [field]="person.job.title"></edit-field>

这会导致输入字段完全编辑原始 object 中的标题字段。问题是 person.job.title 是一个字符串,而不是 object 或数组,所以它不是通过引用传递的。

我有 2 个想法可以解决问题: 1) 将 "person.job.title" 作为字符串传递:

<edit-field [field]="'person.job.title'"></edit-field>

<edit-field field="person.job.title"></edit-field>

并且在组件 class 中用“.”分割:

let fields = this.field.split('.');

然后执行 while 循环以通过引用访问该字段。

我们还可以做 2 个输入:

<edit-field-component [fieldRef]="person.job" [field]="'title'"></edit-field-component>

然后在组件内部执行 this.fieldRef[this.field]

我想知道是否有其他更干净的方法来实现这一点。

Java脚本就像Java一样是按值传递的,他们从来没有提供按引用传递。所以在你的情况下,你最好的选择是直接传递你的人对象。即使它会在你的函数中被复制,副本仍然引用同一个对象,所以改变副本中的一个字段也会改变原始中的相应字段。

如果您想将您的对象或您的对象的 属性 引用到您的组件,您需要创建一个类型为 eventEmitter 的 @Output 属性。

@Input('field') field: any;
@Output() fieldChange = new EventEmitter();

请注意使用 "Change" 后缀词命名您的输出 属性。它会自动检测你的对象的变化并通知你的主要对象。

[field]="person.job.title"one-way bindingperson.job.title 的更改会传播到 field,但反之则不会)

[(field)]="person.job.title" 将实现 two-way bindingfieldChange 方法所做的更改也会传播回 person.job.title

基本上,您想要完成双向绑定 - 即更改对象值:例如 person.job.title 更新您的新编辑组件,而且从您的编辑组件所做的更改也会反映回对象值。

在 Angular 中,这意味着您必须双向绑定:

<edit-field [field]="person.job.title"  (change)="person.job.title=$event"></edit-field>

您的 edit-field 组件有一个 @Output 属性,只要有人输入它就会发出更改后的值。 @Output 属性 发出的值将在变量 $event 中,您只需将其分配回要更新的 属性。

因此,您的 EditFieldComponent 可能类似于:

@Component({
   .....
   template: `
      <input (input)="change.emit($event.target.value)" ....   />
   `
})
export class EditFieldComponent {
   change = new EventEmitter();
}

上面的意思是,每当输入事件在您的输入字段上触发时,组件的 change 输出 属性 将发出输入字段的新值。

===========

如果您理解以上所有内容,那么 Angular 为这个确切的场景提供了一个小捷径。如果组件的输出 属性 以特定方式命名,则可以简化编写双向绑定的方式。

因此,如果您的输入 属性 是 field,并且您将输出命名为 属性 fieldChange,您可以使用一些奇特的语法来减少多少你必须打字。

<edit-field [field]="person.job.title"  (fieldChange)="person.job.title=$event"></edit-field>

相当于:

<edit-field [(field)]="person.job.title"></edit-field>