1

我是 Angular2 的新手,正在尝试让自定义组件使用管理 Mongo.Collection 对象注册表的服务。我的问题是,加载集合后,我似乎无法让 Angular 刷新 UI。

如果你看一下下面的代码,你会看到有一个注入了 DatasetService 的组件。该服务管理集合的注册表。我猜这个问题与 Meteor.autorun() 方法将处理从 Angular“区域”中取出&我需要以某种方式将进程重新注入到 Angular 区域/摘要中这一事实有关?

客户端和服务器:

export const Meetings = new Mongo.Collection<any>('meetings');

仅限服务器

Meteor.publish('meetings', function(options: any) {
  return Meetings.find({});
});

仅限客户

class Dataset {
  cursor: Mongo.Cursor<any>;
  loading: boolean = true;

  constructor( public collection: Mongo.Collection<any> ) {
    Tracker.autorun(() => {
      this.loading = true;
      Meteor.subscribe('meetings', {}, () => {
        this.cursor = this.collection.find({});
        this.loading = false;
      });
    });
  }
}

@Injectable()
class DatasetService {
  datasets: Dataset[] = [];

  register( id: string, collection: Mongo.Collection<any> ) : Dataset {
    return this.datasets[id] = new Dataset( collection, options );
  }
}

@Component({
  selector: 'meetings-list',
  template: `<ul><li *ngFor="let meeting of meetings.cursor">{{meeting.name}}</li></ul>`,
  viewProviders: [DatasetService]
})
class MeetingsListComponent extends MeteorComponent implements OnInit {
  meetings: Dataset;

  constructor(private datasetService: DatasetService) {
    super();
  }

  ngOnInit() {
    this.meetings = this.datasetService.register( 'meetings', Meetings );
  }

  checkState() {
    console.log(this.loading);
  }
}

如果我加载页面,会议列表不会出现。但是,如果我通过单击按钮手动调用“checkState()”,则会刷新 UI 并呈现会议。

任何帮助,清晰或替代方法来实现我正在尝试做的事情将不胜感激!

4

1 回答 1

1

你是对的。触发更改的代码来自 Angular2 区域之外,因此您需要将其推送到区域中以执行更改。为此,您需要将 NgZone 注入到您的服务中。然后您可能需要将其传递给 Dataset 实例,因为那是应该触发更新的代码所在的位置。例如,这可能有效:

import { Injectable, NgZone, Inject } from '@angular/core';

class Dataset {
  cursor: Mongo.Cursor<any>;
  loading: boolean = true;

  constructor( public collection: Mongo.Collection<any>, zone: NgZone ) {
    Tracker.autorun(() => {
      this.loading = true;
      Meteor.subscribe('meetings', {}, () => {
        zone.run(() => {  //<-- new line
          this.cursor = this.collection.find({});
          this.loading = false;
        });               //<-- end of new line
      });
    });
   }
}

@Injectable()
class DatasetService {
  datasets: Dataset[] = [];
  private zone: NgZone;

  // Inject Here
  constructor(@Inject(NgZone)zone: NgZone) { this.zone = zone; }

  register( id: string, collection: Mongo.Collection<any> ) : Dataset {
    //Add zone to Dataset constructor, 
    // not sure before or after options (not sure where options comes from or goes
    return this.datasets[id] = new Dataset( collection, this.zone, options );
  }
}
于 2016-09-06T21:24:45.473 回答