this.myService.myEvent.toRx().subscribe() 调用但没有 DOM 刷新(区域触发器)
this.myService.myEvent.toRx().subscribe() called but no DOM refresh (Zone trigger)
我正在玩 ng2-play starter from pawel 的 angular2 alpha 40。
示例在打字稿中。
我有这样的服务 MovieList:
export class Movie {
selected: boolean = false
constructor(public name:string, public year:number, public score:number) {}
}
export class MovieListService {
list: Array<Movie>
selectMovie = new EventEmitter();
constructor() {
this.list = [new Movie('Star Wars', 1977, 4.4)];
}
add(m:Movie) {
this.list.push(m);
}
remove(m:Movie) {
for(var i = this.list.length - 1; i >= 0; i--) {
if(this.list[i] === m) {
if(m.selected) this.selectMovie.next();
this.list.splice(i, 1);
}
}
}
select(m:Movie) {
this.list.map((m) => m.selected = false);
m.selected = true;
this.selectMovie.next(m);
}
}
我有一个显示电影列表的组件,可以通过单击它来 select 一个,它在上面的服务中调用 select()
。
我还有另一个组件(在同一级别,我不想使用 (selectmovie)="select($event)"
)订阅电影 selection 事件,如下所示:
@Component({
selector: 'movie-edit',
})
@View({
directives: [NgIf],
template: `
<div class="bloc">
<p *ng-if="currentMovie == null">No movie selected</p>
<p *ng-if="currentMovie != null">Movie edition in progress !</p>
</div>
`
})
export class MovieEditComponent {
currentMovie:Movie
constructor(public movieList: MovieListService) {
this.movieList.selectMovie.toRx().subscribe(this.movieChanged);
setTimeout(() => { this.movieChanged('foo'); }, 4000);
}
movieChanged(f:Movie = null) {
this.currentMovie = f;
console.log(this.currentMovie);
}
}
使用 eventEmitter 上的 .toRx().subscribe()
订阅事件。
movieChanged()
被调用,但模板中没有任何反应。
我尝试使用 timeout()
调用相同的函数,并且在模板中反映了更改。
movieChanged 函数需要电影对象而不是字符串。尝试更改以下代码
setTimeout(() => { this.movieChanged('foo'); }, 4000);
至
setTimeout(() => { this.movieChanged(new Movie('Troy', 2000 , 8)); }, 4000);
问题似乎是 subscribe
expects an Observer
或在您传递普通函数时充当观察者的三个函数。所以在你的代码中,我只是将 movieChanged
更改为观察者而不是回调函数。
movieChanged: Observer = Observer.create(
(f) => { this.currentMovie = f; }, // onNext
(err) => {}, // onError
() => {} // onCompleted
);
有关示例,请参阅 this plnkr。很高兴看到您的要求的最小工作示例,这样我的解决方案将更接近您正在寻找的东西。但如果我理解正确,这应该对你有用。我只是使用一个按钮来触发更改,而不是 select。
更新
您可以通过将函数传递给订阅者方法来避免创建 Òbserver(很明显,直接传递函数和使用 class 方法是有区别的,不知道为什么不同)
this.movieList.selectMovie.toRx().subscribe((m: Movie = null) => {
this.currentMovie = m;
});
备注
EventEmitter is being refactored, so in future releases next
will be renamed to emit
.
注2
Angular2 移动到 @reactivex/rxjs
但在 plnkr 中我无法直接使用那些库(没有找到任何 cdn)。但是您可以在自己的项目中尝试使用这些库。
希望对您有所帮助。
我正在玩 ng2-play starter from pawel 的 angular2 alpha 40。 示例在打字稿中。
我有这样的服务 MovieList:
export class Movie {
selected: boolean = false
constructor(public name:string, public year:number, public score:number) {}
}
export class MovieListService {
list: Array<Movie>
selectMovie = new EventEmitter();
constructor() {
this.list = [new Movie('Star Wars', 1977, 4.4)];
}
add(m:Movie) {
this.list.push(m);
}
remove(m:Movie) {
for(var i = this.list.length - 1; i >= 0; i--) {
if(this.list[i] === m) {
if(m.selected) this.selectMovie.next();
this.list.splice(i, 1);
}
}
}
select(m:Movie) {
this.list.map((m) => m.selected = false);
m.selected = true;
this.selectMovie.next(m);
}
}
我有一个显示电影列表的组件,可以通过单击它来 select 一个,它在上面的服务中调用 select()
。
我还有另一个组件(在同一级别,我不想使用 (selectmovie)="select($event)"
)订阅电影 selection 事件,如下所示:
@Component({
selector: 'movie-edit',
})
@View({
directives: [NgIf],
template: `
<div class="bloc">
<p *ng-if="currentMovie == null">No movie selected</p>
<p *ng-if="currentMovie != null">Movie edition in progress !</p>
</div>
`
})
export class MovieEditComponent {
currentMovie:Movie
constructor(public movieList: MovieListService) {
this.movieList.selectMovie.toRx().subscribe(this.movieChanged);
setTimeout(() => { this.movieChanged('foo'); }, 4000);
}
movieChanged(f:Movie = null) {
this.currentMovie = f;
console.log(this.currentMovie);
}
}
使用 eventEmitter 上的 .toRx().subscribe()
订阅事件。
movieChanged()
被调用,但模板中没有任何反应。
我尝试使用 timeout()
调用相同的函数,并且在模板中反映了更改。
movieChanged 函数需要电影对象而不是字符串。尝试更改以下代码
setTimeout(() => { this.movieChanged('foo'); }, 4000);
至
setTimeout(() => { this.movieChanged(new Movie('Troy', 2000 , 8)); }, 4000);
问题似乎是 subscribe
expects an Observer
或在您传递普通函数时充当观察者的三个函数。所以在你的代码中,我只是将 movieChanged
更改为观察者而不是回调函数。
movieChanged: Observer = Observer.create(
(f) => { this.currentMovie = f; }, // onNext
(err) => {}, // onError
() => {} // onCompleted
);
有关示例,请参阅 this plnkr。很高兴看到您的要求的最小工作示例,这样我的解决方案将更接近您正在寻找的东西。但如果我理解正确,这应该对你有用。我只是使用一个按钮来触发更改,而不是 select。
更新
您可以通过将函数传递给订阅者方法来避免创建 Òbserver(很明显,直接传递函数和使用 class 方法是有区别的,不知道为什么不同)
this.movieList.selectMovie.toRx().subscribe((m: Movie = null) => {
this.currentMovie = m;
});
备注
EventEmitter is being refactored, so in future releases next
will be renamed to emit
.
注2
Angular2 移动到 @reactivex/rxjs
但在 plnkr 中我无法直接使用那些库(没有找到任何 cdn)。但是您可以在自己的项目中尝试使用这些库。
希望对您有所帮助。