Angular2:可观察对象内部的变化检测
Angular2: Change detection inside observable
刚刚我尝试了我的第一个应用程序与Angular2 RC3(使用Angular-CLI),我失去了这个…
我对变量word
的"变化检测"有一个问题。我在Observable的subscribe
方法中更新了word
变量,但是没有检测到任何变化。
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
内执行,但没有。
我做错了什么?
额外
:
我与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没有被angular zone修补。
要解决这个问题,可以使用zone.run(...)
显式地强制执行回到angular区域:
@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)
),请相应地调整代码。
您最终可以显式调用ChangeDetectorRef
类的detectChanges
方法:
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(); // <---------
});
}
相关文章:
- 检测数据的变化
- 如何检测和打印变化变量LESS
- 检测 DIV 的高度何时变化,而无需轮询或突变观察者
- jQuery:检测Flexbox内部的位置
- 检测observableArray是否发生变化
- 检测Ionic中特定的应用程序状态变化
- 如何在呈现页面后使用 Java 脚本检测 dom 元素值的值是否有任何变化(例如,任何输入或复选框值更改)
- 使用 jquery 检测变量变化
- 如何检测用户点击了内部或外部链接
- 如何动态检测浏览器视口大小的变化
- 角度2的变化检测是否总是从根部开始
- 变化检测中的角度2+GridStack错误
- jquery ui:检测输入中的首次时间变化
- 正在检测是否在构造函数内部使用了新关键字
- 角度 2 服务中的变化检测
- Firefox中的Angular2变化检测无限循环
- angular2在变化检测后在画布上绘制图像
- angularjs 2 rc4变化检测:检查后表达发生变化
- Angular2:可观察对象内部的变化检测
- 帧源变化检测