在MongoObservable.Collection中展示文档的数量

时间:2017-05-02 20:45:26

标签: angular meteor rxjs

我在我的Meteor应用程序中使用了rxjs MongoObservable.Collection,并且无法找到一种简单的方法来获取我的集合中的文档数量。

在下面的代码中,当我的集合中有文档时,我的loadData()方法工作正常,但由于Observable从未填充任何数据,如果是空集合,我无法弄清楚如何管理这个案件。有什么想法吗?

文件summary.collection.ts:

export const Summaries = new MongoObservable.Collection<Summary>('summary');

文件summary.publish.ts:

Meteor.publish('summaries', () => {
  return Summaries.collection.find();
});

文件summary.component.ts:

@Component({
  selector: 'summary',
  template,
})
export class SummaryPage {
  loadData() {
    Meteor.subscribe('summaries');
    this.summariesModel = Summaries.find()
      .debounce(() => Observable.interval(500));

    this.summariesModel.subscribe(summaries => {
      summaries.forEach(summary => {
        if (summary.length === 0)
          this.state = 'empty'; // <== never reach this point
        else
          this.state = 'loaded';
      });
    });

    this.summariesModel.zone();
  } 
}

文件summary.html:

    <tr *ngFor="let model of summariesModel | async">
      <td> {{model.country}} </td>
      <td> {{model.customer}} </td>
    </tr>

编辑:为了更清楚,我多次调用此loadData()方法,并且每次实际传递不同的查询时,如Summaries.find({customer:'XYZ Ltd.' )。

我在模板(html)中使用this.state以提供3种不同的状态(通过* ngIf):为空(显示“此客户没有数据”) ; 加载已加载

所以我没有必要无限期地等待在这个查询中出现一些东西。

此外,作为一种解决方法(或者这可能是唯一的解决方案),我在服务器中创建了一个方法,该方法返回给定特定查询的文档总数。而且,在客户端,我不得不这样做:

asyncSummariesCount(query) {
  return new Promise((resolve, reject) => {
    Meteor.call('getSummariesCount', query, (err, count) => {
      if (err) count = 0;
      resolve(count);
    });
  });
}

async loadData() {
...
  if (await this.asyncSummariesCount(query) === 0) {
    this.state = 'empty';
    return;
  }
...
}

它工作得很好,但是由于客户端可以访问整个已发布的集合,因此应该更容易获得文档的总数。

1 个答案:

答案 0 :(得分:0)

与else block异步会对你有帮助吗?这是一个例子:

https://plnkr.co/edit/JZf8BaIfFceJx8HQHGi8

  @Component({
    selector: 'my-app',
    template: `
      <div>
        <div *ngIf="obs$ | async; else elseBlock">not empty</div>
        <ng-template #elseBlock>empty</ng-template>
      </div>
    `,
   })
   export class App {
    s = new Subject();
    obs$;

    constructor() {
       this.obs$ = this.s.asObservable();
       // publish after 5 sec
       setTimeout(()=>
            {this.s.next('aaa');}
        , 5000);
    }
  }