Eri*_*icJ 40 typescript angular2-changedetection angular
我想用udpate我的应用程序视图,由服务事件触发.
我的一个服务注入了ChangeDetectorRef.编译工作正常,但是当App被引导时,我在浏览器中出现错误:No provider for ChangeDetectorRef!.
我以为我需要将它添加到我的AppModule中,但我找不到任何表明它在我可以导入的模块中的文档.我尝试将类本身添加到导入数组,但这导致了错误.尝试将其添加到模块中的providers数组时,我也遇到错误.这是我的服务的简化版本:
import {Injectable, ChangeDetectorRef } from '@angular/core';
@Injectable()
export class MyService {
private count: number = 0;
constructor(private ref: ChangeDetectorRef){}
increment() {
this.count++;
this.ref.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)
和app模块:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { MyService } from './my.service';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [ MyService ],
booststrap: [ AppComponent ]
})
export AppModule {}
Run Code Online (Sandbox Code Playgroud)
UPDATE
我已经尝试删除我对ChangeDetectorRef的使用,但我仍然遇到同样的问题.我猜我更新了我的System JS配置有什么问题.
我最初使用angular-cli创建了应用程序,并且由于他们没有更新它而试图自己更新Angular.随着Angular 2.0.0的最终版本,他们更新了angular-cli以使用最新版本的angular.所以我将尝试使用他们的升级程序,希望这会更好.
更新2
webpack/angular-cli更新进展顺利.我现在使用Angular 2.0.0和angular-cli 1.0.0-beta14进行应用程序构建.我仍然在浏览器中得到相同的错误.我尝试从服务中删除ChangeDetectorRef,但我没有.我有两个服务.如果我从两个服务中删除它,那么我的应用程序加载正常,并且运行良好,除了我尝试使用ChangeDetectorRef的地方.一旦我将其添加回其中一个文件,浏览器就会抱怨无法为其找到提供商.
我尝试在我的模块中导入它,但它不是一个模块,所以转换器抱怨.我尝试在我的模块中列出它是一个提供者,但它没有提供属性,所以转换器抱怨.如果我尝试将它放在声明数组中的类似问题.
Mac*_*der 35
ChangeDetectorRef不是在这里使用的选项.它正在寻找给定组件及其子组件的更改.
在你的情况下,最好使用ApplicationRef:
import {Injectable, ApplicationRef } from '@angular/core';
@Injectable()
export class MyService {
private count: number = 0;
constructor(private ref: ApplicationRef) {}
increment() {
this.count++;
this.ref.tick();
}
}
Run Code Online (Sandbox Code Playgroud)
我检查了这个解决方案,Observables它没有任何问题:
import { ApplicationRef, Injectable } from '@angular/core';
import { Observable, ReplaySubject } from "rxjs/Rx";
import * as childProcess from 'child_process';
@Injectable()
export class Reader {
private output: ReplaySubject<string> = new ReplaySubject<string>(0);
constructor(private ref: ApplicationRef) {
var readerProcess = childProcess.spawn('some-process');
readerProcess.stdout.on('data', (data) => {
this.output.next(data.toString());
this.ref.tick();
});
}
public getOutput():Observable<string> {
return this.output;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个使用它的组件:
import {Component} from '@angular/core';
import { ReplaySubject, Observable } from "rxjs/Rx";
import { Reader } from './reader/reader.service';
@Component({
selector: 'app',
template: `
output:
<div>{{output}}</div>
`
})
export class App {
public output: string;
constructor(private reader: Reader) {}
ngOnInit () {
this.reader.getOutput().subscribe((val : string) => {
this.output = val;
});
}
}
Run Code Online (Sandbox Code Playgroud)
如果要从服务触发更改,但允许组件控制它们是否,何时以及如何响应,则另一个选择是设置订阅。
在您的服务中,添加EventEmitter:
changeDetectionEmitter: EventEmitter<void> = new EventEmitter<void>();
Run Code Online (Sandbox Code Playgroud)
当服务中发生某些事情可能需要触发变更检测周期时,只需发出:
this.changeDetectionEmitter.emit();
Run Code Online (Sandbox Code Playgroud)
现在,在使用此服务的任何组件中,如果他们需要侦听可能的更改触发器,则可以订阅并做出适当的反应:
this.myService.changeDetectionEmitter.subscribe(
() => {
this.cdRef.detectChanges();
},
(err) => {
// handle errors...
}
);
Run Code Online (Sandbox Code Playgroud)
我有点喜欢这种方法,因为它让变更检测控制在它所属的组件上,但允许我将逻辑集中在服务中。该服务不需要知道有关UI的任何信息,它只是通知正在收听的任何人发生了什么变化。
| 归档时间: |
|
| 查看次数: |
22142 次 |
| 最近记录: |