Angular 2+ 组件的双向绑定
Two Way Binding on an Angular 2+ Component
我有一个 Ionic 应用程序,我在其中创建了一个组件来显示对象的一些数据。我的问题是,当我更新托管组件的父级中的数据时,组件中的数据不会更新:
我的-card.component.ts
@Component({
selector: 'my-card',
templateUrl: './my-card.html'
})
export class MyCard {
@Input('item') public item: any;
@Output() itemChange = new EventEmitter();
constructor() {
}
ngOnInit() {
// I do an ajax call here and populate more fields in the item.
this.getMoreData().subscribe(data => {
if (data.item){
this.item = data.item;
}
this.itemChange.emit(this.item);
});
}
}
我的-card.html
<div class="comment-wrapper" *ngFor="let subitem of item.subitems">
{{subitem.title}}
</div>
在父级中我使用这样的组件:
<my-card [(item)]="item"></my-card>
以及父级的 ts 文件:
@IonicPage()
@Component({
selector: 'page-one',
templateUrl: 'one.html',
})
export class OnePage {
public item = null;
constructor(public navCtrl: NavController, public navParams: NavParams) {
this.item = {id:1, subitems:[]};
}
addSubItem():void{
// AJAX call to save the new item to DB and return the new subitem.
this.addNewSubItem().subscribe(data => {
let newSubItem = data.item;
this.item.subitems.push(newSubItem);
}
}
}
因此,当我调用 addSubItem() 函数时,它不会更新组件并且 ngFor 循环仍然不会显示任何内容。
如果 getMoreData
方法 returns 是一个可观察对象,则此代码需要如下所示:
ngOnInit() {
// I do an ajax call here and populate more fields in the item.
this.getMoreData().subscribe(
updatedItem => this.item = updatedItem
);
}
订阅导致异步操作执行,returns 一个可观察对象。当数据从异步操作返回时,它会执行提供的回调函数并将项目分配给返回的项目。
您使用 @Input()
装饰器将项目声明为:
@Input('item') public item: any;
但是你在上面使用了two-way绑定:
<my-card [(item)]="item"></my-card>
如果只是输入,应该是
<my-card [item]="item"></my-card>
现在,如果您调用 addSubItem()
,它应该会显示新添加的项目。
this.item = this.getMoreData();
如果您将 getMoreData()
放入您的卡片组件中,则没有任何意义,因为您想使用通过 @Input()
传递的项目
您的组件交互有点不对劲。查看 Angular 文档 (https://angular.io/guide/component-interaction). Specifically, using ngOnChanges (https://angular.io/guide/component-interaction#intercept-input-property-changes-with-ngonchanges) or use a service to subscribe and monitor changes between the parent and the child (https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service) 上的指南。
您在发出 api 请求时破坏了 object 引用。您正在分配新值,即覆盖您从 parent 获得的输入值,并且 object 不再指向相同的 object,而是 item
你的 child 是一个完全不同的 object。如你所愿two-way-binding,我们可以利用Output
:
Child:
import { EventEmitter, Output } from '@angular/core';
// ..
@Input() item: any;
@Output() itemChange = new EventEmitter();
ngOnInit() {
// I do an ajax call here and populate more fields in the item.
this.getMoreData(item.id).subscribe(data => {
this.item = data;
// 'recreate' the object reference
this.itemChange.emit(this.item)
});
}
现在我们再次拥有相同的 object 引用,无论您在 parent 中做什么,都会反映在 child 中。
我有一个 Ionic 应用程序,我在其中创建了一个组件来显示对象的一些数据。我的问题是,当我更新托管组件的父级中的数据时,组件中的数据不会更新:
我的-card.component.ts
@Component({
selector: 'my-card',
templateUrl: './my-card.html'
})
export class MyCard {
@Input('item') public item: any;
@Output() itemChange = new EventEmitter();
constructor() {
}
ngOnInit() {
// I do an ajax call here and populate more fields in the item.
this.getMoreData().subscribe(data => {
if (data.item){
this.item = data.item;
}
this.itemChange.emit(this.item);
});
}
}
我的-card.html
<div class="comment-wrapper" *ngFor="let subitem of item.subitems">
{{subitem.title}}
</div>
在父级中我使用这样的组件:
<my-card [(item)]="item"></my-card>
以及父级的 ts 文件:
@IonicPage()
@Component({
selector: 'page-one',
templateUrl: 'one.html',
})
export class OnePage {
public item = null;
constructor(public navCtrl: NavController, public navParams: NavParams) {
this.item = {id:1, subitems:[]};
}
addSubItem():void{
// AJAX call to save the new item to DB and return the new subitem.
this.addNewSubItem().subscribe(data => {
let newSubItem = data.item;
this.item.subitems.push(newSubItem);
}
}
}
因此,当我调用 addSubItem() 函数时,它不会更新组件并且 ngFor 循环仍然不会显示任何内容。
如果 getMoreData
方法 returns 是一个可观察对象,则此代码需要如下所示:
ngOnInit() {
// I do an ajax call here and populate more fields in the item.
this.getMoreData().subscribe(
updatedItem => this.item = updatedItem
);
}
订阅导致异步操作执行,returns 一个可观察对象。当数据从异步操作返回时,它会执行提供的回调函数并将项目分配给返回的项目。
您使用 @Input()
装饰器将项目声明为:
@Input('item') public item: any;
但是你在上面使用了two-way绑定:
<my-card [(item)]="item"></my-card>
如果只是输入,应该是
<my-card [item]="item"></my-card>
现在,如果您调用 addSubItem()
,它应该会显示新添加的项目。
this.item = this.getMoreData();
如果您将 getMoreData()
放入您的卡片组件中,则没有任何意义,因为您想使用通过 @Input()
您的组件交互有点不对劲。查看 Angular 文档 (https://angular.io/guide/component-interaction). Specifically, using ngOnChanges (https://angular.io/guide/component-interaction#intercept-input-property-changes-with-ngonchanges) or use a service to subscribe and monitor changes between the parent and the child (https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service) 上的指南。
您在发出 api 请求时破坏了 object 引用。您正在分配新值,即覆盖您从 parent 获得的输入值,并且 object 不再指向相同的 object,而是 item
你的 child 是一个完全不同的 object。如你所愿two-way-binding,我们可以利用Output
:
Child:
import { EventEmitter, Output } from '@angular/core';
// ..
@Input() item: any;
@Output() itemChange = new EventEmitter();
ngOnInit() {
// I do an ajax call here and populate more fields in the item.
this.getMoreData(item.id).subscribe(data => {
this.item = data;
// 'recreate' the object reference
this.itemChange.emit(this.item)
});
}
现在我们再次拥有相同的 object 引用,无论您在 parent 中做什么,都会反映在 child 中。