【问题标题】:div ngIf if the firestore collection does not return any documentdiv ngIf 如果 firestore 集合不返回任何文档
【发布时间】:2019-04-10 14:55:15
【问题描述】:

我正在使用 AngularFire2,如果函数没有从某个集合返回任何文档,我基本上想要做的是显示一个 div,即零。如果你返回一个或更多的文档,这个 div 应该会消失。

我尝试了以下方法,但没有得到预期的结果:

service.ts

size: number;
contadorSize;

contadorEventosPropios() {
    const user = firebase.auth().currentUser;

    this.contadorSize  = this.afs
        .collection('eventos', ref => ref.where('autorId', '==', user.uid))
        .get().subscribe(snap => {
          this.size = snap.size;
          console.log(this.size);
        });
    return this.contadorSize;
}

component.ts

size: boolean;
contadorSize: number;

constructor( public fs: FirebaseService, private afs: AngularFirestore ) {}

ngOnInit() {
    this.contadorSize = this.fs.contadorEventosPropios();

    if (this.contadorSize === 0 ) {
        return this.size = true;
    } else {
       return this.size = false;
    }
}

component.html

<div *ngIf="size">
  ...
</div>

【问题讨论】:

  • 用 return 语句反转 this.size = true/false。喜欢:this.size = true;返回;
  • @JacopoSciampi 我试过了,但即使函数返回 0,div 仍然没有显示

标签: angular google-cloud-firestore angularfire2


【解决方案1】:

您没有正确处理异步调用。向所有变量添加类型是个好主意,这样更容易看出意图和出错的地方。

尝试将您的服务更改为:


contadorEventosPropios(): Observable<{ size: number; }> {
    const user = firebase.auth().currentUser;

    return this.afs
        .collection('eventos', ref => ref.where('autorId', '==', user.uid))
        .get();
}

你的组件类似于:

size: boolean;

constructor( public fs: FirebaseService, private afs: AngularFirestore ) {}

ngOnInit() {
    this.fs.contadorEventosPropios().subscribe(result => {
      if (result.size === 0 ) {
          this.size = true;
      } else {
         this.size = false;
      }
    });

【讨论】:

  • @Stanley De Boer result 不是数字。它仍然行不通。结果是一个包含size 属性的对象
  • @kasptom 感谢您指出这一点。现在好看了吗?
  • @Stanley 是的。我还会从 if / else 子句中删除 return 关键字
【解决方案2】:

您正在返回 Subscription 对象。您可以将其更改为:

service.ts

size: number;
contadorSize;

contadorEventosPropios(): Observable<number> {
    const user = firebase.auth().currentUser;

    this.contadorSize  = this.afs
        .collection('eventos', ref => ref.where('autorId', '==', user.uid))
        .get()
        .map(snap => { // instead of subscribe
          this.size = snap.size;
          console.log(this.size);
          return snap.size;
        });

    return this.contadorSize;
}

component.ts

size: boolean;
// contadorSize: number; // wrong
contadorSize: Observable<number>; // corrected

constructor( public fs: FirebaseService, private afs: AngularFirestore ) {}

ngOnInit() {
    this.contadorSize = this.fs.contadorEventosPropios();
    // removed
}

component.htmlasync pipe 可以解决问题)

<div *ngIf="(contradorSize | async) === 0">
  ...
</div>

【讨论】:

  • 虽然做了一些小的修改,但效果很好。当我添加.map 时,它给了我一个错误:The property 'map' does not exist in the type 'Observable &lt;QuerySnapshot&gt;'. Ts 然后我必须将它包装在.pipe 然后在component.ts 中我必须分配counterSize: any。有了这个我设法工作,但我必须更新以检测变化。
  • counterSize 是什么?和contadorSize一样吗?我还注意到我的回答中有一个错误。在 component.ts 中 contadorSize 应该是 Observable&lt;number&gt; 类型
  • 我已经编辑了答案(更改了contadorSize 的类型)。将它与模板中的async 一起使用是否需要“更新以检测更改”?
  • counterSizecontadorSize 相同,抱歉翻译。如果您需要更新页面以检测更改,请使用async。有没有办法在不更新的情况下实现它?同样的也不错。
猜你喜欢
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 1970-01-01
  • 2020-02-27
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多