Meteor with Angular2,单次从集合中获取所有条目

Meteor with Angular2 , Fetching all entries from a collection in single shot

我已经成功地将 meteor 与 angular2 整合在一起,但是当从集合中获取数据时,一次拍摄遇到困难,步骤如下:

集合名称:订单详情 记录数 : 1000

服务器: 已创建发布文件以订阅合集:

Meteor.publish('orderFilter', function() {
         return OrderLineDetails.find({});
   });

客户:

this.dateSubscription = 
     MeteorObservable.subscribe('orderFilter').subscribe(()=> {
        let lines = OrderDetails.find({expectedShipDate:{$in:strArr}},{fields: 
    {"expectedShipDate":1,"loadNo":1},sort:{"expectedShipDate":1}}).fetch();
   });

在这行属性中获取所有集合条目,但无法订阅更改

当我尝试下面的一个时,

OrderDetails.find({expectedShipDate:{$in:strArr}},{fields:{"expectedShipDate":1,"loadNo":1},sort:{"expectedShipDate":1}}).zone().subscribe(results => {
     // code to loop the results
});

在此我可以订阅集合更改,但结果循环了 1000 次,因为集合中有 1000 个条目。

有没有什么方法可以一次性获取整个集合条目并同时订阅集合中的更改?

我认为这不可能。当您订阅 Observable 时,它​​会将值作为 "stream" 处理,不一定是循环。我已经看到一些临时的辅助方法可以同步处理数据,但订阅所需的时间并没有减少。查看这篇文章以了解引擎盖下的外观... A simple Observable implementation

不过,您可以将其设置为只循环一次。

按照我设置该场景的方式,集合仅循环一次(在应用程序启动时在构造函数中)并检测集合中的更改。在您的情况下,它看起来像:

  values: YourModel[] = []; //this is an array of models to store the data
  theData: Observable<YourModel[]>;
  errors: string[];
  subFinished: boolean = false;

  constructor(){
    this.theData = OrderDetails.find({expectedShipDate:{$in:strArr}},{fields:{"expectedShipDate":1,"loadNo":1},sort:{"expectedShipDate":1}}).zone();
    MeteorObservable.subscribe('orderFilter').subscribe();

    //push data onto the values array
    this.theData.subscribe(
      value => this.values = value,
      error => this.errors.push("new error"),
      () => this.subFinished = true
    );
  }

"values" 数组随着数据库发生的任何变化而更新。

是的,有几种方法可以做到这一点,主要取决于您希望如何处理数据。

如果一次拥有所有东西很重要,那么使用如下方法:

MeteorObservable.call('getAllElements', (err, result) => {
  // result.length === all elements
})

在服务器端做

Meteor.methods({
   getAllElements:function(){return myCollection.find().fetch()}
})

现在,如果你想听变化,当然你必须做一个订阅,如果你想降低订阅量,使用 rxjs 的 debounceTime() 函数,例如(从你的代码):

this.theData.debounceTime(400).subscribe(value => ...., err =>)

这将在订阅之前等待一定时间collection。

现在,根据您的意图:监听更改并同时获取所有内容,您可以将这两种方法结合起来,虽然不是最有效的,但可以是有效的。

正如@Rager 所解释的那样,可观察对象接近于流,因此当您在 miniMongo 上填充数据时(前端 collection 您在 find() 数据时使用并在您订阅出版物时填充)它会开始递增,直到 collection 同步。

由于 miniMongo 是在您订阅发布时填充的,而不是在您查询游标时填充的,因此您可以:

  1. 尝试 debouceTime() 方法
  2. 在订阅发布后使用 Meteor.Method,然后同步两个结果,将方法的第一个响应作为起点,然后使用来自Collection.find().subscribe(collectionArray => ..., err=>) 在更改应用时做你想做的事(不推荐,除非您对此有特定的用例)

此外,.zone() 函数专门用于在 Angular 的事件周期中强制 re-render。如果您正在处理 collections 的数据而不是在 ngFor* 循环中呈现它,我建议不要使用它。如果您使用的是 ngFor* 循环,请改用异步管道 ngFor="let entry of Collection | async"