Observable/subscrption 更改属性时 ngOnChanges 不触发
ngOnChanges not firing when attribute changed by Observable/subscrption
我正在尝试在 Observable
/subscribe
完成后做一些事情。我正在 subscribe( onNext )
方法中更改 Input
属性,但 ngOnChanges
永远不会触发。
我应该做些什么不同的事情?
import { Component, EventEmitter,
OnInit, AfterViewInit, OnChanges, SimpleChanges,
Input, Output
} from '@angular/core';
@Component({
templateUrl: 'myTemplate.html'
, providers: [ NamesService ]
})
export class MyPage {
@Input() names: any[];
constructor( public namesSvc: NamesService) {}
ngOnInit() {
this.getNames$()
}
getNames$() : void {
this.nameService.get().subscribe(
(result)=>{
this.names = result;
console.log(`getNames$, names=${this.names}`);
// I could doSomething() here, but it doesn't seem like the correct place
// doSomething()
}
, error => this.errorMessage = <any>error
)
}
ngOnChanges(changes: SimpleChanges) : void {
// changes.prop contains the old and the new value...
console.warn(`>>> ngOnChanges triggered`)
if (changes["names"]) {
console.warn(`>>> ngOnChanges, names=${changes["names"]}`)
this.doSomething()
}
}
doSomething(){
console.log("doing something");
}
}
那是"as designed"
ngOnChanges()
仅在更改检测更新绑定到 @Input()
时调用。如果从某处强制更改输入,则不会调用它。
只需将 names
设为 getter/setter,以便每次更新 属性 时执行代码。
正如 Günter 所说,根据我的理解,它并不像那样工作...使用 Observables 时,您可以使用 Observable.next()
功能手动触发更改。这里的技巧是您必须从您的服务中 return 一个 Observable
- 这可以像这样完成:
import {Observable, Subject} from "rxjs/Rx"; // remember the '/Rx', it got me...
export class NamesService {
private initialNames: Array<string> = ["Joe", "Jack", "Pete"];
get(){
let names: Subject<Array<string>> = new Subject<Array<string>>();
names.next(this.initialNames);
setTimeout(() => {
this.initialNames.push('someOtherNames');
names.next(this.initialNames);
}, 1000);
return names.asObservable();
}
}
然后像您已经完成的那样订阅它,当 .next()
运行时它将触发 .subscribe()
方法的更改。
不过,我建议将其与 get 方法分开,您可以拥有自己的 onNameUpdate()
方法,return 可观察数组或类似的方法。
我正在尝试在 Observable
/subscribe
完成后做一些事情。我正在 subscribe( onNext )
方法中更改 Input
属性,但 ngOnChanges
永远不会触发。
我应该做些什么不同的事情?
import { Component, EventEmitter,
OnInit, AfterViewInit, OnChanges, SimpleChanges,
Input, Output
} from '@angular/core';
@Component({
templateUrl: 'myTemplate.html'
, providers: [ NamesService ]
})
export class MyPage {
@Input() names: any[];
constructor( public namesSvc: NamesService) {}
ngOnInit() {
this.getNames$()
}
getNames$() : void {
this.nameService.get().subscribe(
(result)=>{
this.names = result;
console.log(`getNames$, names=${this.names}`);
// I could doSomething() here, but it doesn't seem like the correct place
// doSomething()
}
, error => this.errorMessage = <any>error
)
}
ngOnChanges(changes: SimpleChanges) : void {
// changes.prop contains the old and the new value...
console.warn(`>>> ngOnChanges triggered`)
if (changes["names"]) {
console.warn(`>>> ngOnChanges, names=${changes["names"]}`)
this.doSomething()
}
}
doSomething(){
console.log("doing something");
}
}
那是"as designed"
ngOnChanges()
仅在更改检测更新绑定到 @Input()
时调用。如果从某处强制更改输入,则不会调用它。
只需将 names
设为 getter/setter,以便每次更新 属性 时执行代码。
正如 Günter 所说,根据我的理解,它并不像那样工作...使用 Observables 时,您可以使用 Observable.next()
功能手动触发更改。这里的技巧是您必须从您的服务中 return 一个 Observable
- 这可以像这样完成:
import {Observable, Subject} from "rxjs/Rx"; // remember the '/Rx', it got me...
export class NamesService {
private initialNames: Array<string> = ["Joe", "Jack", "Pete"];
get(){
let names: Subject<Array<string>> = new Subject<Array<string>>();
names.next(this.initialNames);
setTimeout(() => {
this.initialNames.push('someOtherNames');
names.next(this.initialNames);
}, 1000);
return names.asObservable();
}
}
然后像您已经完成的那样订阅它,当 .next()
运行时它将触发 .subscribe()
方法的更改。
不过,我建议将其与 get 方法分开,您可以拥有自己的 onNameUpdate()
方法,return 可观察数组或类似的方法。