0

从数据库订阅数据后,我无法立即更新 UI,我必须单击某处

另外,如果我使用路由器转到另一个页面,它不起作用

@Component({
  selector: 'foo-component',
  template: `
    {{foo}}
  `
})
export class FooComponent extends MeteorComponent {
  foo: string ;

  constructor() {
    super();

    this.subscribe('messages', () => {
      // I cannot change foo value immediately, I have to click somewhere
      this.foo = 'foo';

      // Also if I use the router to go to another page, it does not work
      // this.router.navigate(['Home']);
    });
  }
}

如何解决这个问题?

4

1 回答 1

1

请注意,新的 angular2-meteor 版本 autoBind默认设置为 true。所以你可能不会再遇到这个问题了。

但是您仍然需要在 Accounts.changePassword 或其他类似的 Accounts.foo() 函数中使用 NgZone。


这个问题是因为那部分代码在 Angular 2 zone 之外运行,您需要在 zone 内运行它以立即更新 UI 或使用路由器转到另一个页面。

这些问题通常发生在哪里?

大多数时候你不这样做。那么你什么时候需要这个?通常在 Meteor 函数的回调中:

   this.autorun(() => {
     // here you need
   });

   this.subscribe('messages', () => {
     // here you need
   });

   this.call('newMessage', (error, result) => {
     // here you need
   });

   Accounts.changePassword(currentPassword, newPassword, error => {
     // here you need
   });

怎么解决?

 this.call('newMessage', (error, result) => {
   this.router.navigate(['Home']);
 });

例如,您需要更改为:

import { NgZone } from '@angular/core';

constructor(private zone: NgZone) {}

this.call('newMessage', (error, result) => {
  this.zone.run(() => {
    this.router.navigate(['Home']);
  });
});

有干净的方法吗?

幸运的是,Angular2-Meteor 可以帮助你完成这项肮脏的工作。

查看Angular2-Meteor API 文档,有一个autoBind参数 forthis.subscribethis.autorun

所以现在你不需要 use this.zone.run,你可以添加一个true

   this.autorun(() => {
     // your code
   }, true);

   this.subscribe('messages', () => {
     // your code
   }, true);
于 2016-07-01T03:15:34.037 回答