Angular2:在可观察的内部更改检测

时间:2016-06-29 12:50:54

标签: javascript typescript angular angular-cli angular2-changedetection

我刚用Angular2 RC3尝试了我的第一个应用程序(使用Angular-CLI),我迷失了...

我的问题是"更改检测"变量In [32]: round(2.5) Out[32]: 2 In [33]: round(3.5) Out[33]: 4 。我更新了Observable的word方法中的word变量,但未检测到任何更改。

app.component.ts

subscribe

我记得在Angular 1中import { Component, Inject, OnInit } from '@angular/core'; import { VoiceRecognitionService } from './voice-recognition.service'; @Component({ moduleId: module.id, selector: 'app-root', template: `<h1>{{word}}</h1>`, // => No prints any update providers: [VoiceRecognitionService], styleUrls: ['app.component.css'] }) export class AppComponent implements OnInit { private voice: VoiceRecognitionService; public word: string = ''; constructor( @Inject(VoiceRecognitionService) voiceRecognition: VoiceRecognitionService) { this.voice = voiceRecognition; } ngOnInit() { this.voice.record('ca') .subscribe(word => { console.log(word); // => Is printing well the new word this.word = `${word}...`; // => No changes detected }); } } 用于类似的情况,我搜索Angular2的同一个,我发现$scope.$apply,我试图在NgZone.run内执行,但没有。

我做错了什么?

非常感谢你。

额外:

我与Observable分享我的服务:

语音-recognition.service.ts

NgZone.run

2 个答案:

答案 0 :(得分:9)

我认为Angulars区域没有修补webkitSpeechRecognition API。

要解决使用zone.run(...)明确强制执行回Angulars区域的问题:

@Injectable()
export class VoiceRecognitionService {

  constructor(private zone:NgZone) {
    /* void */
  }

  /**
   * Record
   * @param {string} language - Language of the voice recognition
   * @returns {Observable<string>} - Observable of voice converted to string 
   */
  record(language: string): Observable<string> {
    return Observable.create((observer) => {
      const { webkitSpeechRecognition }: IWindow = <IWindow>window;
      const recognition = new webkitSpeechRecognition();

      recognition.onresult = (e) => this.zone.run(() => observer.next(e.results.item(e.results.length - 1).item(0).transcript));
      recognition.onerror = (e) => this.zone.run(() => observer.error(e));
      recognition.onend = (e) => this.zone.run(() => observer.completed(e));

      recognition.continuous = true;
      recognition.interimResults = true;
      recognition.lang = language;
      recognition.start();
    });
  }
}

如果回调需要不同数量的参数((e)),请相应调整代码。我只假设了一个参数。

这种方法的优点是该服务的用户不必采取其他措施。

答案 1 :(得分:0)

您最终可以明确调用detectChanges类的ChangeDetectorRef方法:

constructor( @Inject(VoiceRecognitionService) voiceRecognition: VoiceRecognitionService,
    private cdr:ChangeDetectorRef) {
  this.voice = voiceRecognition;
}

ngOnInit() {
  this.voice.record('ca')
    .subscribe(word => {
      console.log(word); // => Is printing well the new word
      this.word = `${word}...`; // => No changes detected
      this.cdr.detectChanges(); // <---------
    });
}