编辑30-07-2018 01:57 CET:仍在寻找以下问题的解决方案:
我有以下代码:
getBoolean(dataRef1, dataRef2) {
const myFirstObservable = this.af.object(dataRef1).valueChanges();
const mySecondObservable = this.af.object(dataRef2).valueChanges();
return combineLatest(myFirstObservable, mySecondObservable).pipe(map(([data1, data2]) => data1 && data2)))
}
该代码基本上是做什么的:它将两个可观察对象的结果组合在一起,然后检查每个对象是否返回了任何值。如果两个可观察值都具有值,则返回 true ,否则返回 false 。
到目前为止,一切正常。然后,我从View中调用该方法,为可观察对象提供动态节点引用,并使用布尔值添加条件元素:
<div *ngIf="getBoolean('dataN', 'dataK') | async"> My lovely div content goes here</div>
但是,我的div根本不显示在视图上。
有人可以告诉我我做错了什么,可以帮助我达到预期的结果吗?
答案 0 :(得分:1)
getBoolean()
未返回任何内容。订阅回调内部的返回将返回订阅。一种实现此逻辑的方法。
getBoolean(dataRef1, dataRef2): Observable<boolean> {
const myFirstObservable = this.af.object(dataRef1).valueChanges();
const mySecondObservable = this.af.object(dataRef2).valueChanges();
return combineLatest(myFirstObservable, mySecondObservable, (data1, data2) => data1 && data2)
}
神奇之处在于:您使用async
管道link订阅了HTML,该管道将为您订阅:
<div *ngIf="getBoolean('dataN', 'dataK') | async"> My lovely div content goes here</div>
答案 1 :(得分:0)
首先,您的应用程序陷入了无限循环,因为您将视图与返回的函数绑定在一起,该函数不会返回任何内容。此外,我不建议从视图中绑定函数,而是将其绑定到变量。
您可能尝试添加一个BehaviorSubject,它将视图和逻辑绑定到正确的值。
我已经做了一个沙箱,只是检查它是否有效,而且确实可以。
TL; DR-我只构造了两个BehaviorSubject来操纵 第三个,在您的情况下是所需的布尔值。我绑定 通过CombineLatest将div分配给第三个BSubject,它可以正常工作。关键是要始终绑定一个有效的变量,该变量通过combinateLatest的订阅进行更新,而我通过BehaviorSubject更新其值
k1 = new BehaviorSubject<boolean>(false);
k2 = new BehaviorSubject<boolean>(false);
k3 = new BehaviorSubject<boolean>(false);
k3$: Observable<boolean>;
constructor() {
this.k3$ = this.k3.asObservable();
}
ngOnInit() {
combineLatest(this.k1.asObservable(), this.k2.asObservable(), (d1, d2) => {
return d1 && d2;
}).subscribe(b => {
console.log(b);
this.k3.next(b);
});
}
toggle1 = () => {
this.k1.next(true);
};
toggle2 = () => {
this.k2.next(true);
};
和HTML:
<div *ngIf='k3$ | async'>
Example
</div>
这是可行的,请尝试查看示例并将其投影到您的代码中。 Check the CodeSandbox Example
祝你好运!
答案 2 :(得分:0)
最有可能的问题是,您正在模板中调用getBoolean('dataN', 'dataK')
方法。每次更改检测时,Angular都会调用getBoolean
方法,该方法返回一个新的Observable。旧版本已取消订阅async
,只有新版本处于活动状态。
同时combineLatest
运算符要求所有源Observable至少发射一次,这不太可能发生,因为async
在不断变化的检测周期中进行订阅/取消订阅,该周期可能多次发生。第二。
所以我建议您将Observable存储在一个属性中:
public obs$ = combineLatest(myFirstObservable, mySecondObservable, (data1, data2) => data1 && data2);
然后仅在模板中使用obs$ | async
。
最终,您可以在getBoolean
内添加一些逻辑,以检查obs$
是否存在,如果存在则直接将其返回。