[英]Getting updated values from Observable's subscription
我注意到有关Angular 2中Observables的一些内容,我无法解释,并希望一个好的模型可以揭示我。
我的理解是,在订阅Observable时,你基本上有两种策略来消耗它发出的值:
流与异步管道相结合,如:
myTextSubscription$ = SomeObservable.subscribe();
{{ myTextSubscription$ | async }}
或者从订阅处理程序中提取值并绑定它:
myTextSubscription$ = SomeObservable.subscribe(text => this.text = text);
{{ text }}
好吧,问题是我已经尝试了几次使用后一种方法,我从来没有设法更新text
值,除非我在处理程序中调用this.cdRef.markForCheck()
。 我想这种基本场景不应该需要手动调用changeDetection - 至少我没有看到在任何截屏视频或教程中使用过。
这听起来对任何人都很熟悉吗? 这是我对该方法的错误理解,还是Angular 2中的错误?
编辑:
上面的代码已被抽象,因为我认为问题可以在更抽象的层面上解释。
我不记得第一个案例,当它咬我,但现在Observable来自ngrx商店,所以它基本上是这样的:
this.text$ = store.let((state$: Observable<State>) => {
return state$.select(state => state.text);
});
如果SomeObservable
以某种方式在Angulars区域之外初始化或使用某些未被zone.js转换的API,则通常会发生这种情况。
我们需要看看SomeObservable
是如何精确构建的,以确定无疑。
实际上,在使用async
时不应订阅observable。 这就是为什么async
是那么棒的原因。 它在初始化/销毁组件时处理subscribe
和unsubscribe
。
所以代替:
JS
myTextSubscription$ = SomeObservable.subscribe();
HTML
{{ myTextSubscription$ | async }}
你应该宁愿:
JS
myTextSubscription$ = SomeObservable;
HTML
{{ myTextSubscription$ | async }}
我想澄清变量名中$的使用:
- 观察值应以“$”为后缀
- 当你使用订阅时,你没有得到可观察的
关于惯例:
JS
let someObservable$ = ...;
HTML
{{ someObservable$ | async }}
请记住:
- 当您使用订阅时,您需要从observable 手动取消订阅,但路由器和http除外)
- 当你有.subscribe
,返回的值是Subscription
类型(这意味着你可以取消订阅)
所以这里是一个更清洁的结构的概述(不使用异步管道):
@Component({
selector: '...',
templateUrl: '...html',
styleUrls: ['...css']
})
export class AppComponent implements OnInit, OnDestroy {
private myText: string;
private myTextSubscription: Subscription;
constructor() { }
ngOnInit() {
// I assume here that you declared an observable called "someObservable"
this.myTextSubscription = someObservable$.subscribe(text => this.myText = text);
}
ngOnDestroy() {
// as our observable is not coming from router or http, we need to manually
// unsubscribe in order to avoid memory leaks
this.myTextSubscription.unsubscribe();
}
}
编辑1:使用您更新的示例,以下是如何将它与@ngrx一起使用:
@Component({
selector: '...',
templateUrl: '...html',
styleUrls: ['...css']
})
export class AppComponent implements OnInit, OnDestroy {
private text: string;
private textSub: Subscription;
constructor(private store$: Store<State>) {
this.textSub =
store$.select('yourState')
.subscribe((state: State) => this.text = state);
}
ngOnDestroy() {
this.textSub.unsubscribe();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.