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)。但是您可以在自己的项目中尝试使用这些库。

希望对您有所帮助。