![](/img/trans.png)
[英]Angular2: How to reset input property after it is changed from child component programatically but not changed in parent binding?
[英]How to make child component detects object (@Input()) from parent component has changed in Angular
我有一个来自父组件的对象,也收到了与此类似的子组件:
{
attribute: 'aaaa',
attribute2: [
{
value
},
{
value
},
{
value
},
]
}
此对象是来自父组件的@Input
。 当我对attribute2
数组中的对象进行更改时,我希望子组件检测到所做的更改然后进行更新。 由于这是一个对象,我无法让它工作,所以我在父组件中克隆了整个对象( this.objet = _.cloneDeep(this.object
),然后子组件检测到发生了变化。
有没有其他方法可以不克隆整个对象? 提前致谢
编辑:
export class ChildComponent implements OnInit, OnChanges {
@Input() public object: any;
}
html
<div>
<span>{{object.attribute}}</span>
<div *ngFor="let items of object.attribute2">{{item.value}}</div>
</div>
export class ParentComponent implements OnInit {
public object: any;
updateObject() {
this.object.attribute2[1] = 'Changed value';
this.object = _.cloneDeep(this.object);
}
}
html
<div>
<child-component [object]="object"></child-component>
</div>
一种有效的方法是使用 EventEmitter 和服务通信来触发子组件中的更改。
@Tony 提到的方法是使用 ngOnChanges()。 这是检测有界属性变化的一个很好的捷径,但是随着你添加越来越多的绑定,从长远来看,使用这个钩子会影响你的应用程序,因为它会在每次任何绑定属性改变时运行,无论你是否想要它调用。
因此,对于基于服务的通信,我创建了一个示例
Stackblitz: https ://stackblitz.com/edit/angular-fgut7t
要点: https : //gist.github.com/stupidly-logical/a34e272156b498513505127967aec851
在这个例子中,我在添加新数据时使用@Input() 将一个数组绑定到子组件,该数组由父级更新,最新的值传递给服务,然后该服务发出此值。 子组件订阅该值并执行相关代码。
服务:
import { Injectable, EventEmitter } from '@angular/core';
@Injectable({
providedIn: "root"
})
export class DataService {
dataUpdated:EventEmitter<any> = new EventEmitter();
constructor() { }
setLatestData(data) {
this.dataUpdated.emit(data);
}
}
子组件 TS
import { Component, OnInit, Input } from '@angular/core';
import { DataService } from '../data-service.service';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input() allData: [];
latestData: any;
constructor(private dataService: DataService) { }
ngOnInit() {
this.dataService.dataUpdated.subscribe((data) => {
this.latestData = data;
});
}
}
子组件 HTML
<p>
Latest Data: {{ latestData }}
</p>
<h3>List:</h3>
<li *ngFor="let data of allData">
{{ data }}
</li>
父组件 TS
import { Component } from '@angular/core';
import { DataService } from './data-service.service'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
dataArr = [];
constructor(private dataService: DataService){}
onAddTimestamp() {
let timestamp = new Date();
this.dataArr.push(timestamp);
this.dataService.setLatestData(timestamp);
}
}
父组件 HTML
<hello name="{{ name }}"></hello>
<p>
Start editing to see some magic happen :)
</p>
<button
(click)="onAddTimestamp()"
>
Add Timestamp
</button>
<app-child
[allData] = "dataArr"
></app-child>
在您的组件中使用 ngOnChanges() 生命周期方法。
ngOnChanges 在数据绑定属性被检查之后和视图和内容子项被检查之前被调用,如果其中至少一个发生了变化。
有些像这样
@Input() object: string;
ngOnChanges(changes: SimpleChanges) {
console.log(changes.object.currentValue);
// You can also use object.previousValue and
// object.firstChange for comparing old and new values
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.