以简化的方式,我有一个Angular2组件和一个像这样的输入对象:
class MyObject{
Prop1:string;
Prop2:Number;
}
@Component()
export class MyComponent{
@Input() myObject: MyObject;
DoSomethingIfProp1Change(){
console.log(myObject.Prop1);
}
}
如何检测Prop1是否已从Hostcomponent更改,然后从MyComponent内部执行DoSomethingIfProp1Change方法?
答案 0 :(得分:5)
实际上,默认情况下,Angular2会在更新对象引用而不是其内容时检测更改。但是,可以使用DoCheck
接口更改此默认行为。
在您的情况下(检测到属性已更新到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');
}
}
更新prop1
属性的值时,将调用doSomethingIfProp1Change
方法。
请参阅此plunkr:http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview。
答案 1 :(得分:4)
您可以使用observables来支持订阅者的通知。 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);
}
}
使用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`
}
}
}