3

编辑 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)))
}

基本上代码所做的是:它结合了两个 observables 的结果,然后检查每个 observables 是否返回了任何值。如果两个 observable 都有值,则返回true否则返回false

到目前为止一切顺利,一切都按预期工作。然后我从我的视图中调用该方法,为可观察对象提供动态节点引用,并使用布尔值添加条件元素:

<div *ngIf="getBoolean('dataN', 'dataK') | async"> My lovely div content goes here</div>

但是,我的 div 根本不显示在我的视图上。

有人可以告诉我我错在哪里并帮助我达到我想要的结果吗?

4

3 回答 3

1

最有可能的问题是您正在调用getBoolean('dataN', 'dataK')模板中的方法。在每次更改检测时,Angular 都会调用getBoolean返回新 Observable 的方法。旧的被取消订阅async,只有新的处于活动状态。

同时,combineLatest运营商要求所有源 Observables 至少发出一次,这不太可能发生,因为async订阅/取消订阅可能会在每秒多次发生的变化检测周期中发生。

所以我建议你将 Observable 存储在一个属性中:

public obs$ = combineLatest(myFirstObservable, mySecondObservable, (data1, data2) => data1 && data2);

然后只obs$ | async在模板中使用。

最终,您可以在其中添加一些逻辑getBoolean来检查是否obs$存在,如果存在,您将按原样返回。

于 2018-07-30T08:52:21.660 回答
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管道链接订阅 HTML ,它将为您订阅:

<div *ngIf="getBoolean('dataN', 'dataK') | async"> My lovely div content goes here</div>
于 2018-07-29T22:17:56.647 回答
0

首先,您的应用程序陷入无限循环,因为您将视图与返回的函数绑定,该函数不返回任何内容。此外,我不建议从视图绑定函数,而是绑定到变量。
您可能会尝试添加一个 BehaviorSubject,它将视图和逻辑绑定到正确的值。
我制作了一个沙箱来检查它是否有效,并且确实有效。

TL;DR - 我只是构造两个 BehaviorSubject 来操纵第三个的值,在您的情况下是所需的布尔值。我通过 combineLatest 将 div 绑定到第三个 BSubject 并且它可以工作。关键是始终保持一个有效的变量来绑定,它通过combineLatest的订阅得到更新,我通过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>

这是可行的,请尝试查看示例并将其投影到您的代码中。 检查 CodeSandbox 示例


祝你好运 !

于 2018-07-30T00:06:31.517 回答