子组件有两个数据绑定输入属性,一个是错字string
(inputVariable
),另一个是string[]
(inputArray
)。
import {Component, Inject, Input} from 'angular2/core';
@Component(
{
selector: 'child-app',
template: `
{{inputVariable}}
<input type="button" (click)="onButtonOneClick()" value="changeFoo">
<ul>
<li *ngFor="#el of inputArray"> {{el}} </li>
</ul>
<input type="button" (click)="onButtonTwoClick()" value="ChangeLi">
`
})
export class ChildAppComponent {
@Input() inputVariable: string;
@Input() inputArray: string[];
onButtonOneClick() {
this.inputVariable = 'new string';
}
onButtonTwoClick() {
this.inputArray[0] = 'New element String';
}
}
父组件具有相同的属性,并在模板([inputArray]="inputArray" inputVariable="inputVariable"
)
import {Component} from 'angular2/core';
import {ChildAppComponent} from './childApp.component';
@Component({
selector: 'my-app',
template:
`
{{inputVariable}}
<input type="button" (click)="onButtonOneClick()" value="changeFoo">
<ul>
<li *ngFor="#el of inputArray"> {{el}} </li>
</ul>
<input type="button" (click)="onButtonTwoClick()" value="ChangeLi">
<hr>
<child-app [inputArray]="inputArray" inputVariable="inputVariable"> </child-app>
`,
directives: [ChildAppComponent]
})
export class AppComponent {
inputVariable: string = 'foo';
inputArray: string[] = ['one', 'two'];
onButtonOneClick() {
this.inputVariable = 'new string';
}
onButtonTwoClick() {
this.inputArray[0] = 'New element String';
}
}
父组件和子组件内的按钮点击会更改相应属性的值(buttonOne
- &gt; inputVariable
&amp; buttonTwo
- &gt; inputArray
)
单击第二个按钮(更改string[]
属性值)时,在父组件和子组件中都会发生更改
点击第一个按钮(更改string
属性值)时,更改仅在父母或子女内部发生(相应于我点击的组件按钮)
string
属性之间进行双向绑定?答案 0 :(得分:4)
如果您希望父组件看到更新,则只能通过引用进行更改。这是你的数组的情况,但不是你的字符串属性(更常见的是具有基本类型的属性)。
要使每种情况都有效,您需要利用输出和双向绑定:
@Component({
(...)
})
export class ChildAppComponent {
@Input() inputVariable: string;
@Output() inputVariableChange: EventEmitter<string> = new EventEmitter();
@Input() inputArray: string[];
onButtonOneClick() {
this.inputVariable = 'new string';
this.inputVariableChange.emit(this.inputVariable);
}
(...)
}
这可以通过以下方式从父组件中使用:
<child-app [inputArray]="inputArray"
[(inputVariable)]="inputVariable"> </child-app>
请参阅[(...])
语法。在这种情况下,当此属性的子组件发生更新时,inputVariable
将透明地更新。
您可以注意到,只有当绑定的引用发生更改时,Angular2才会检测到更改,而不会更新相应的内容(对象属性或数组中的元素)。
这是默认行为,但您可以根据DoCheck
界面提供自己的行为。针对此用例,请参阅此问题:
答案 1 :(得分:1)
对于从子级到父级的绑定,您需要使用@Output()
import {Component, Inject, Input} from 'angular2/core';
@Component({
selector: 'child-app',
template: `
{{inputVariable}}
<input type="button" (click)="onButtonOneClick()" value="changeFoo">
<ul>
<li *ngFor="#el of inputArray"> {{el}} </li>
</ul>
<input type="button" (click)="onButtonTwoClick()" value="ChangeLi">
`
})
export class ChildAppComponent {
@Input() inputVariable: string;
// v added
@Output() inputVariableChange:EventEmitter<string> = new EventEmitter<string>();
@Input() inputArray: string[];
// v added
@Output() inputArrayChange:EventEmitter<string[]> = new EventEmitter<string[]>();
onButtonOneClick() {
this.inputVariable = 'new string';
this.inputVariableChange.emit(this.inputVariable);
}
onButtonTwoClick() {
this.inputArray[0] = 'New element String';
this.inputArrayChange.emit(this.inputArray);
}
}
在父母的中使用它
{{inputVariable}}
<input type="button" (click)="onButtonOneClick()" value="changeFoo">
<ul>
<li *ngFor="#el of inputArray"> {{el}} </li>
</ul>
<input type="button" (click)="onButtonTwoClick()" value="ChangeLi">
<hr>
<!-- v added ( )
<child-app [(inputArray)]="inputArray" inputVariable="inputVariable"> </child-app>
命名是相关的。仅当输入和输出名为[(xxx)]="yyy"
和@Input() xxx
时,快捷键绑定语法@Output() xxxChange
才有效。否则必须使用长形式。
[xxx]="zzz" (xxxChange)="zzz = $event"
Angular不会检查对象或数组中的更改,它只会检查对象或数组是否是与以前不同的对象或数组。
如果仅修改了对象的属性或仅添加/删除/替换了某个元素,Angular将不会注意到 - 例如在*ngFor
中
<ul>
<li *ngFor="#el of inputArray"> {{el}} </li>
</ul>
如果绑定到属性而不仅仅绑定元素项,则*ngFor
会识别更改
<ul>
<li *ngFor="#el of inputArray"> {{el.someProp}} </li>
</ul>
解决方法是例如创建一个新数组
this.inputArray.slice();
或使用新的(beta.2)trackBy
功能
另请参阅http://www.bennadel.com/blog/3020-understanding-object-identity-with-ngfor-loops-in-angular-2-beta-3.htm
创建一个副本(新的和不同的数组),Angular将其识别为更改。