我已经创建了一个用作交换机的组件。 您可以像使用复选框一样使用它。 这是一个精简版。
我-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); } }我的计划是这样使用它:
家长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) } }同样,这是简化的,但我认为说明了我的期望。 我的期望是,当单击开关时,视图会从“关闭”更新为“开启”,并且会记录该选项的值。 问题是记录的值如下所示:
{options: {option1: false}}我的信念是迭代的项目是只读的。 我知道我可以解决这个问题,但我想知道我想要做的事情是可能的,还是不明智的,以及为什么它不起作用。
I have created a component that is meant to be a switch. You would use it much the same as you would a checkbox. This is a stripped down version.
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); } }My plan is to use it like this:
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) } }Again, this is simplified, but I think illustrates what I expect. My expectation is that when the switch is clicked, the view updates from "Off" to "On" and the value of the option is logged. The problem is that the value that is logged looks like this:
{options: {option1: false}}My belief is that the items being iterated over are read-only. I know that I can work around this issue, but I would like to know if what I am trying to do is possible, or ill-advised, and also why it doesn't work.
最满意答案
Angular将[(x)]语法“去糖”成属性绑定的x输入属性和事件绑定的xChange输出属性。 - 参考
因此,如果您为输入属性value命名,则必须将输出属性命名为valueChange :
@Output() valueChange = new EventEmitter <boolean> ();这是你想念的唯一一块拼图。 您现在在父组件和子组件之间具有双向数据绑定。
如果要在子项更改/ emit() s值时执行某些逻辑,请捕获父组件中的(valueChange)事件:
(valueChange)='logItem(item)'>Plunker
我也建议
console.log(JSON.stringify(item))Angular "de-sugars" the [(x)] syntax into an x input property for property binding and an xChange output property for event binding. -- reference
Therefore, if you name your input property value, you must name your output property valueChange:
@Output() valueChange = new EventEmitter <boolean> ();That's the only piece of the puzzle you were missing. You now have two-way databinding between a parent and a child component.
If you want to execute some logic when the child changes/emit()s the value, catch the (valueChange) event in the parent component:
(valueChange)='logItem(item)'>Plunker
I also suggest
console.log(JSON.stringify(item))更多推荐
发布评论