typescript 检测组件输入的嵌套属性的更改
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36267119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
detect change of nested property for component input
提问by Xaver
In a simplified way I have an Angular2 Component and an input object like this:
以一种简化的方式,我有一个 Angular2 组件和一个像这样的输入对象:
class MyObject{
Prop1:string;
Prop2:Number;
}
@Component()
export class MyComponent{
@Input() myObject: MyObject;
DoSomethingIfProp1Change(){
console.log(myObject.Prop1);
}
}
How can I detect if Prop1 was changed from Hostcomponent and then execute the DoSomethingIfProp1Change method from inside MyComponent?
如何检测 Prop1 是否已从 Hostcomponent 更改,然后从 MyComponent 内部执行 DoSomethingIfProp1Change 方法?
回答by Thierry Templier
In fact, by default Angular2 detects changes when object reference is updated not its content. But this default behavior can be changed by using the DoCheck
interface.
事实上,默认情况下,Angular2 会在对象引用而不是其内容更新时检测更改。但是这个默认行为可以通过使用DoCheck
接口来改变。
In your case (detecting that a property was updated into the myObject
object, you could use the following approach:
在您的情况下(检测到属性已更新到myObject
对象中,您可以使用以下方法:
@Component({
selector: 'my-component',
(...)
})
export class MyComponent implements DoCheck {
@Input() myObject: MyObject;
differ: any;
constructor(differs: KeyValueDiffers) {
this.differ = differs.find([]).create(null);
}
ngDoCheck() {
var changes = this.differ.diff(this.myObject);
if (changes) {
changes.forEachChangedItem((elt) => {
if (elt.key === 'prop1') {
this.doSomethingIfProp1Change();
}
});
}
}
doSomethingIfProp1Change() {
console.log('doSomethingIfProp1Change');
}
}
When the value of the prop1
property is updated, the doSomethingIfProp1Change
method is called.
当prop1
属性的值被更新时,该doSomethingIfProp1Change
方法被调用。
See this plunkr: http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview.
请参阅此 plunkr:http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview 。
回答by Günter Z?chbauer
You can use observables to support notification of subscribers. Angular itself doesn't provide support for observing changes of internal object state.
您可以使用 observable 来支持订阅者的通知。Angular 本身不支持观察内部对象状态的变化。
class MyObject{
constructor() {
this.prop1Change$ = new Observable(observer =>
this._prop1Observer = observer).share(); // share() allows multiple subscribers
this.prop2Change$ = new Observable(observer =>
this._prop2Observer = observer).share();
console.debug(this._prop2Observer);
}
prop1Change$: Observable<string>;
private _prop1Observer: Observer;
_prop1:string;
get prop1():string { return this._prop1 };
set prop1(value:string) {
this._prop1 = value;
this._prop1Observer && this._prop1Observer.next(value);
}
prop1Change$: Observable<number>;
private _prop2Observer: Observer;
_prop2:Number;
get prop2():number { return this._prop2 };
set prop2(value:number) {
this._prop2 = value;
console.debug(this);
this._prop2Observer && this._prop2Observer.next(value);
}
}
This code could be shortened by using Subject
but Observable
should be favored over Subject
.
这段代码可以通过使用来缩短,Subject
但Observable
应该优先于Subject
.
@Component()
export class MyComponent{
@Input() myObject: MyObject;
count2:number;
DoSomethingIfProp1Change(){
console.log(myObject.prop1);
}
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
console.log('changes');
if(changes['myObject']) {
if(this.prop2Subscription) {
this.prop2Subscription.unsubscribe();
}
this.prop2Subscription = this.myObject.prop2Change$.subscribe(value => {
this.count2 = value;
console.log('count2: ' + value);
});
// same for `prop2`
}
}
}