2

以前有人问过这个问题,但我找不到有帮助的答案。我希望 oResult 在调用后更改其值。答案必须适合运行 ng2、meteor 和 angular-meteor。谢谢!

/// <reference path="../../typings/angular2-meteor.d.ts" />

import {Input, Component, View, NgZone} from 'angular2/core';
import {MeteorComponent} from 'angular2-meteor';

@Component({
  selector: 'testcall',
  template: `
    <button (click)="testCall()">Get TestCall Data</button>
    <code><pre>{{oResult}}</pre></code>
  `
})

export class TestCall extends MeteorComponent {

  oResult:any

  constructor(private _ngZone: NgZone) {
    super();
    this.oResult = JSON.stringify({res: 'start'});
  }

  testCall(): void {
    Meteor.call('testCall', function(error,result) {
      if (error) {
        console.log('failed', error);
      } else {
          console.log('successful call', result);
          this._ngZone.run(() => {
              this.oResult = result
          });
      }
    });
  }
}

编辑

我已经缩短了代码并试图探索“this”是否是问题所在。没有 angular-meteor 组件会影响 Meteor.call 的执行。但是 ng2 在调用执行后仍然无法更改模板。我尝试过使用和不使用 NgZone。可能会转储 ng2,因为我肯定没有大脑或时间来陷入这种琐碎的事情!

/// <reference path="../../typings/angular2-meteor.d.ts" />

import {Input, Component, View} from 'angular2/core';

@Component({
  selector: 'testcall',
  template: `
    <button (click)="testCall()">Get TestCall Data</button>
    <code><pre>{{oResult}}</pre></code>
  `
})

export class TestCall {

  oResult:any

  testCall(): void {
    Meteor.call('testCall', (error:any, result:any) => error ? 
    console.log('failed', error) : 
    (this.oResult=result, console.log('successful call', result, this.oResult)));
  }
}

编辑

这段笨拙的代码符合一种时尚。谁能建议如何使 Meteor.call 成为 setTimeout 的回调?

  testCall(): void {
    var self:any = this
    Meteor.call('testCall', (error:any, result:string) => error ?
      console.log('failed', error) :
      (self.oResult=result, console.log('successful call', self.oResult)));
    setTimeout(()=>{
      this.oResult=self.oResult;
    },2000);
  }
4

3 回答 3

1

我个人更喜欢整个异步回调逻辑在 Angular 区域内同步运行。

export class TestComponent {
  oResult: any;

  constructor(private ngZone: NgZone) {
  }

  testCall(): void {
    Meteor.call('testCall', (error, result) => this.ngZone.run(() => {

      if (error)
        console.log('failed', error);
      else {
        console.log('successful call', result);
        this.oResult = result;
      }

    }));
  }
}
于 2016-11-30T10:45:43.423 回答
0
export class TestCall extends MeteorComponent {

  oResult:any

  constructor(private zone: NgZone) {
    super();
    this.oResult = JSON.stringify({res: 'start'});
  }

  testCall(): void {
    Meteor.call('testCall', function(error,result) {
      if (error) {
        console.log('failed', error);
      } else {
          console.log('successful call', result);
        this.zone.run(() => { // do updates within Angular zones 
          this.oResult = result
        });
      }
    });
  }
}

另请参阅手动触发 Angular2 更改检测

于 2016-02-06T13:46:51.163 回答
0

3 个周末后(我是一名周末编码员),我发现了一些有用的东西!

这似乎不需要 ng2-meteor 包。

/// <reference path="../../typings/angular2-meteor.d.ts" />

import {Component, View, NgZone} from 'angular2/core';

@Component({
  selector: 'testcall',
  template: `
    <button (click)="testCall()">Get TestCall Data</button>
    <div>{{oResult}}</div>
  `,
  inputs: ['oResult']
})


export class TestCall {

  oResult:any

  constructor(private _ngZone: NgZone) {
  }

  testCall(): void {

      var promise = function() {
        return new Promise((resolve, reject) =>
          Meteor.call('testCall', (error:any, result:string) => error ? reject(error) : resolve(result))
        );
      };

      promise()
        .then(
          (result) => {
            this._ngZone.run(()=>{
              this.oResult = result;
              console.log(result);
            })
          }
        )
  }
}
于 2016-02-20T18:31:07.780 回答