angular - 错误:使用“defer”时“observableFactory 不是函数”
问题描述
我创建了一个 Angular 9 指令,该指令仅在用户通过身份验证时才显示 HTMl 元素:
<div *authenticated>
Message for Members
</div>
指令代码是:
@Directive({
selector: '[authenticated]'
})
export class AuthenticatedDirective implements OnInit, OnChanges {
constructor(private template: TemplateRef<any>, private container: ViewContainerRef, private authenticationService: AuthenticationService) { }
ngOnInit() {
this.authenticationService.isSignedIn().subscribe(x => {
x ? this.container.createEmbeddedView(this.template) : this.container.clear();
});
}
ngOnChanges() {
this.authenticationService.isSignedIn().pipe(
distinctUntilChanged()
).subscribe(x => {
x ? this.container.createEmbeddedView(this.template) : this.container.clear();
});
}
}
当我运行代码时,我收到错误:
TypeError: observableFactory is not a function. (In 'observableFactory()', 'observableFactory' is an instance of ZoneAwarePromise) — defer.js:8
我检查了authenticationService.isSignedIn()
方法,我有:
isSignedIn(): Observable<boolean> {
return defer(this.manager.getUser()).pipe(map((user: User) => !user.expired));
}
该方法this.manager.getUser()
返回 aPromise<User>
所以我defer
用来返回一个Observable
.
如果我defer
改为from
然后它工作...
但我不应该使用defer
吗?
解决方案
你只是用defer()
错了方法。它将回调作为每次新观察者订阅时调用的参数。当您使用它时,defer(this.manager.getUser())
它试图将返回值getUser()
用作一种方法,我猜它不是,所以它会引发错误。
相反,您应该像这样使用它:
defer(() => this.manager.getUser())
现在每个新订阅都会调用这个方法并defer()
订阅它。我不知道你是否应该使用它。这取决于getUser()
内部做什么。如果它总是返回相同的 Observable 那么你不需要defer
. 如果它返回不同的 Observables(例如使用不同的参数发出 HTTP 请求),那么您需要使用defer()
.