1

在打字稿中,RxJS Observable.flatMap 似乎与使用 Observable.fromPromise(promise) 创建的 Observable 的行为不正确。

我怀疑它不会触发更改检测。

我有这 2 个功能(在 _httpClient 类中):

ObservableFromPremise() : Observable<boolean>{
        var promise =  this._storage.getJson('authToken').then((token) => {
            return true;
        });
        return Observable.fromPromise(promise)
}

BasicObservable() : Observable<boolean>{
     return Observable.create(observer => {
         observer.next(true);
         observer.complete();
     });
}

当我这样做时:

  public get = (url: string) : Observable<Response>  => {

       return this.ObservableFromPremise()
        .flatMap((x) => {
                return this.http.get(url, {headers:this._headers})
                    .map( (responseData) => {
                        return responseData.json();
                    });
           });
    }

我的视图未更新,我需要单击某处(如按钮)以显示检索到的数据。

但是当我使用BasicObservable() 而不是ObservableFromPremise()时,我的视图会更新。

以下是我处理函数 get(在 UserConnector 类中)的方式:

public makeRequest = (id: number): Observable<User> => {
    return this._httpClient.get('http://jsonplaceholder.typicode.com/posts/1')
        .map((item:any) => {
            return new User({
                id: item.id,
                userId: item.userId,
                title: item.title,
                body: item.body
            });

        });
}

在我的页面中:

public myItems: User;

constructor(private userConnector: UserConnector) {

}

ngOnInit() {
        this.getAllItems();
}

private getAllItems(): void {
    this.userConnector
        .makeRequest(this.selectedItem.id)
        .subscribe((data:User) => {
            console.log(data);
            this.myItems = data;
        },
            error => console.log(error),
            () => {console.log('Get Item completed'); });
}

这是模板:

     <div class="thumbnail" *ngIf="myItems">
         <div class="caption">
             <h3>{{myItems.title}}</h3>
             <p>{{myItems.body}}</p>
             <p>{{myItems.id}}</p>
             <p>{{myItems.userId}}</p>
         </div>
     </div>

在这两种情况下,我都在控制台中记录了检索到的数据,以及“获取已完成的项目”,但是使用 ObservableFromPremise(),数据不会在屏幕上更新(直到我单击一个按钮)。

我的配置:angular2 (2.0.0-rc.1), RxJS (5.0.0-beta.6), zone.js (0.6.12), e6-shim (0.35.00)

我能做些什么呢?这是我的代码中的错误吗?在 zone.js 中?在 RxJS 中?

谢谢你的帮助

编辑 1:正如@Richard-Silveira 所建议的,我将使用 NgZone 作为临时解决方法:

.subscribe((data:User) => {
   this._ngZone.run(() => {
      this.myItems = data;
   });
}

我希望有人能分享一个真正的解决方案=)

4

2 回答 2

2

您是否应该使用 NgZone 来更新 UI,如下所示:

private update() {
    this._zone.run(() => {
        console.log('auth updated!');
    });
}

...并在您的订阅中返回后调用此更新函数:

.subscribe((data:User) => {
            this.update();
            this.myItems = data;
        },
于 2016-05-20T17:58:05.587 回答
0

还不让我发表评论,我想我应该建立代表。回答 Angular 4,以防您出于某种原因仍在使用 2。

从它的声音来看,这不是 RxJS 问题(如您的控制台日志所示)。您没有发布组件中的相关位(如装饰器),但我假设您正在使用 OnPush 更改检测策略?如果是这样,那么您需要使用 @Input() 装饰器标记 myItems。

@Input() public myItems: User;

或者,如果您想采用蛮力路线,您可以注入一个 ChangeDetectorRef 并在其上调用 markForCheck()。

constructor(private changeRef: ChangeDetectorRef) {}
...
// in your subscribe()
this.myItems = data;
this.changeRef.markForCheck(); // or call detectChanges() to immediately do so 
于 2017-10-05T14:15:02.667 回答