Angular2:可观察到的内部变化检测 [英] Angular2: Change detection inside observable

查看:63
本文介绍了Angular2:可观察到的内部变化检测的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚使用Angular2 RC3(使用Angular-CLI)尝试了我的第一个应用程序,但我对此一无所知...

Just I tried my first app with Angular2 RC3 (Using Angular-CLI) and I'm lost with this...

我对变量word的更改检测"有问题.我在Observable的subscribe方法中更新了word变量,但未检测到更改.

I have a problem with "Change detection" of variable word. I update the word variable inside the subscribe method of Observable, but no changes detected.

app.component.ts

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
      });
  }
}

我记得在Angular 1中类似情况下使用$scope.$apply,并且在Angular2中进行了相同的搜索,我发现NgZone.run,我试图在NgZone.run内部执行,但是什么也没有.

I remember in Angular 1 the use of $scope.$apply for similar cases and I search the same for Angular2 and I found NgZone.run, I tried to execute inside NgZone.run, but nothing.

我做错了什么?

非常感谢.

我与Observable分享服务

I share my service with the Observable:

voice-recognition.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';

export interface IWindow extends Window {
  webkitSpeechRecognition: any;
}

@Injectable()
export class VoiceRecognitionService {

  constructor() {
    /* 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) => observer.next(e.results.item(e.results.length - 1).item(0).transcript);
      recognition.onerror = observer.error;
      recognition.onend = observer.completed;

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

推荐答案

我假定webkitSpeechRecognition API未被Angulars区域修补.

I assume the webkitSpeechRecognition API is not patched by Angulars zone.

要解决此问题,请使用zone.run(...)强制将执行显式强制返回到Angulars区域:

To work around use zone.run(...) to force the execution back into Angulars zone explicitely:

@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)),请相应地调整代码.我只是假设每个参数一个.

If the callbacks need a different number of parameters ((e)) please adjust the code accordingly. I just assumed one parameter for each.

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

The advantage of this approach is that the users of this service don't have to take additional measures.

这篇关于Angular2:可观察到的内部变化检测的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆