2016-05-20 24 views
1

在打字稿中,似乎RxJS Observable.flatMap在使用Observable.fromPromise(promise)创建的Observable时表现不正确。RxJS和打印稿:Observable.flatMap的行为不正确

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

我有这两个功能(在_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> 

在这两种情况下,我都有在控制台中检索到的数据,以及“Get Item completed”,但使用ObservableFromPremise (),数据不会在屏幕上更新(直到我点击一个按钮)。

我的配置: angular2(2.0.0-RC.1), RxJS(5.0.0-beta.6), zone.js(0.6.12), E6-垫片(0.35.00)

我该怎么办?这是我的代码中的错误吗?在zone.js?在RxJS?

THX对您有所帮助

编辑1: 作为建议由@理查德 - 西尔韦拉我将使用NgZone作为临时解决方法:

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

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

+0

当'this._storage.getJson('authToken')'解析? – paulpdaniels

+0

我想这是数据检索时解决。它来自'ionic-angular': - >从'ionic-angular'导入{Storage,SqlStorage},然后 - > this._storage = new Storage(SqlStorage); –

回答

2

您是否应该使用NgZone更新界面如下:

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

...并在返回后,你的订阅调用此更新功能:

.subscribe((data:User) => { 
      this.update(); 
      this.myItems = data; 
     }, 
+0

似乎更多的解决办法比解决方案imo –

+0

@GeoffreyD,如果你找到了答案,即使你自己发布在这里,请,我真的不能向你证实,这不是一种解决方法,我认为这不是,但我真的很好奇这个问题,因为我解决了这个问题,但是如果有另一个更优雅的方式,我也会更改我的代码... –

+0

好吧没问题,但我真的需要一个解决方案,因为我会用它每次打电话给我的API –

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