Two-Way *ngFor 中的数据绑定
Two-Way data binding in *ngFor
我创建了一个用作开关的组件。您可以像使用复选框一样使用它。这是精简版。
my-switch.component.ts:
import {Component, Input, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'my-switch',
template: `<a (click)='toggle()'>
<span *ngIf='value'>{{onText}}</span>
<span *ngIf='!value'>{{offText}}</span>
</a>`
})
export class MySwitchComponent {
@Input() onText: string = 'On';
@Input() offText: string = 'Off';
@Input() value: boolean;
@Output() change = new EventEmitter <boolean> ();
position: string;
toggle() {
this.value = !this.value;
this.change.emit(this.value);
}
}
我的计划是这样使用它:
parent-component.ts
import {Component} from '@angular/core';
import {MySwitchComponent} from 'my-switch.component';
@Component({
selector: 'my-sites',
directives: [MySwitchComponent]
template: `<table>
<tr *ngFor='let item of items'>
<td>
<my-switch
[(value)]='item.options.option1'
(change)='logItem(item)'>
</my-switch>
</td>
</tr>
</table>`
})
export class MySitesComponent {
items: Object[] = [
{options: { option1: false }}
];
logItem(item) {
console.log(item)
}
}
同样,这是简化的,但我认为说明了我的期望。我的期望是,当单击开关时,视图会从 "Off" 更新为 "On" 并记录选项的值。问题是记录的值如下所示:
{options: {option1: false}}
我相信被迭代的项目是 read-only。我知道我可以解决这个问题,但我想知道我尝试做的事情是否可行,或者 ill-advised,以及为什么它不起作用。
Angular "de-sugars" the [(x)]
syntax into an x
input property for property binding and an xChange
output property for event binding. -- reference
因此,如果您将输入命名为 属性 value
,则必须将输出命名为 属性 valueChange
:
@Output() valueChange = new EventEmitter <boolean> ();
这是您唯一遗漏的拼图。您现在在父组件和子组件之间具有双向数据绑定。
如果你想在子组件改变/emit()
值时执行一些逻辑,在父组件中捕获(valueChange)
事件:
(valueChange)='logItem(item)'>
我也建议
console.log(JSON.stringify(item))
在 parent child 场景中,您可以利用 two-way 与 xxxChange Output property
的绑定,如下所示,,
In Parent - [(xxx)]="someValue"
在Child-@Input xxx: boolean;
@Output() xxxChange = new EventEmitter <boolean> ();
注意xxxChange
属性。你的情况缺少
现在,Look here for the code- Plunker
<td> From Parent - {{item.options.option1}} <--------------------value will keep changing
<my-switch
[(value)]='item.options.option1'> <---------two way binding
</my-switch>
</td>
请注意,[()]
表示双向绑定,因此在 parent 中,您无需使用 (valueChange)="someValue=$event"
来捕获更改. [(value)]='item.options.option1'
会自动将新的或更改的值绑定到 item.options.option1
。
export class MySwitchComponent {
@Input() value: boolean;
@Output() valueChange = new EventEmitter <boolean> (); <----xxxChange output property
...
...
}
我创建了一个用作开关的组件。您可以像使用复选框一样使用它。这是精简版。
my-switch.component.ts:
import {Component, Input, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'my-switch',
template: `<a (click)='toggle()'>
<span *ngIf='value'>{{onText}}</span>
<span *ngIf='!value'>{{offText}}</span>
</a>`
})
export class MySwitchComponent {
@Input() onText: string = 'On';
@Input() offText: string = 'Off';
@Input() value: boolean;
@Output() change = new EventEmitter <boolean> ();
position: string;
toggle() {
this.value = !this.value;
this.change.emit(this.value);
}
}
我的计划是这样使用它:
parent-component.ts
import {Component} from '@angular/core';
import {MySwitchComponent} from 'my-switch.component';
@Component({
selector: 'my-sites',
directives: [MySwitchComponent]
template: `<table>
<tr *ngFor='let item of items'>
<td>
<my-switch
[(value)]='item.options.option1'
(change)='logItem(item)'>
</my-switch>
</td>
</tr>
</table>`
})
export class MySitesComponent {
items: Object[] = [
{options: { option1: false }}
];
logItem(item) {
console.log(item)
}
}
同样,这是简化的,但我认为说明了我的期望。我的期望是,当单击开关时,视图会从 "Off" 更新为 "On" 并记录选项的值。问题是记录的值如下所示:
{options: {option1: false}}
我相信被迭代的项目是 read-only。我知道我可以解决这个问题,但我想知道我尝试做的事情是否可行,或者 ill-advised,以及为什么它不起作用。
Angular "de-sugars" the
[(x)]
syntax into anx
input property for property binding and anxChange
output property for event binding. -- reference
因此,如果您将输入命名为 属性 value
,则必须将输出命名为 属性 valueChange
:
@Output() valueChange = new EventEmitter <boolean> ();
这是您唯一遗漏的拼图。您现在在父组件和子组件之间具有双向数据绑定。
如果你想在子组件改变/emit()
值时执行一些逻辑,在父组件中捕获(valueChange)
事件:
(valueChange)='logItem(item)'>
我也建议
console.log(JSON.stringify(item))
在 parent child 场景中,您可以利用 two-way 与 xxxChange Output property
的绑定,如下所示,,
In Parent - [(xxx)]="someValue"
在Child-@Input xxx: boolean;
@Output() xxxChange = new EventEmitter <boolean> ();
注意xxxChange
属性。你的情况缺少
现在,Look here for the code- Plunker
<td> From Parent - {{item.options.option1}} <--------------------value will keep changing
<my-switch
[(value)]='item.options.option1'> <---------two way binding
</my-switch>
</td>
请注意,[()]
表示双向绑定,因此在 parent 中,您无需使用 (valueChange)="someValue=$event"
来捕获更改. [(value)]='item.options.option1'
会自动将新的或更改的值绑定到 item.options.option1
。
export class MySwitchComponent {
@Input() value: boolean;
@Output() valueChange = new EventEmitter <boolean> (); <----xxxChange output property
...
...
}