2017-02-16 53 views
1

我有一個服務,它通過http獲取請求和後續的映射操作爲我提供了一個觀察值。 在我的組件中,我訂閱了ngOnInit方法中的observable。由於我有分頁功能,我想在用戶點擊分頁器的另一個頁面時向服務發起另一個請求。我怎樣才能做到這一點?我是否必須再次使用新方法訂閱服務,或者是否有可能在組件中初始化可觀察事物,以便我可以使用任何方法?Angular 2第二次請求Observable

export class ListItemsComponent implements OnInit { 
    private _listItems = []; 
    page = 1; 
    constructor(private _listItemsService:ListItemsServiceService) { } 

    ngOnInit() { 
    this._listItemsService.getListItems (this.page) 
    .subscribe(listItems => this._listItems = listItems); 
    } 

    pageChange(page){ 
    this._listItemsService.getListItems (this.page) 
    .subscribe(listItems => this._listItems = listItems); 
    } 

} 

回答

1

您的服務可以公開listItems$作爲一個觀察的情況下,使用專用BehaviourSubject:

@Injectable() 
export class ListItemsService{ 
    public listItems$: Observable<[]> 
    private _listItems: BehaviorSubject<[]>; 

    private dataStore: { 
     listItems: [] 
    }; 

    constructor(@Inject(Http) private http: Http) { 
     this.baseUrl = 'http://localhost/listitemservice/'; 
     this.dataStore = { listItems: [] }; 
     this._listItems = new BehaviorSubject<[]>([]); 
     this.listItems$ = this._listItems.asObservable(); 

    } 
    loadAll() { 
     this.pageChange(1); 
    } 

    pageChange(page) { 
     this.http.get(this.baseUrl + page.id) 
     .subscribe(items => { 
      this.dataStore.listItems = items; 
      this._listItems.next(items); 
     }); 
    } 

然後在你的組件,訂閱時listItems $事件。火災時,存儲列表中的組件類的成員變量:

export class ListItemsComponent implements OnInit { 
    private _listItems = []; 
    constructor(private _listItemsService:ListItemsServiceService) { } 

    ngOnInit() { 
    this._listItemService.listItems$.subscribe(t=> { 
     this._listItems = t; 
    }); 
    this._listItemsService.loadAll();  
    } 

    pageChange(page){ 
    this._listItemsService.pageChange(page); 
    } 

} 

在pageChange,調用whcich進而觸發時listItems $事件ListItemsService的pageChange方法。

+0

我喜歡你的方法。我有一個問題,如果用戶打開一個頁面並立即打開另一個頁面會發生什麼。由於某些原因,第一個請求會比第二個請求晚完成。你知道一些r​​xjs方法來「忘記」以前的請求嗎? – Nikolai

+0

那就是可觀察的定義,是不是?當另一個被解僱時,觀察者會停止一個請求。 – MeMeMax

+0

'pageChange(頁面){ this.http.get(this.baseUrl + page.id) .subscribe(項=> { this.dataStore.listItems =項; this._listItems.next(項目); }); }' 我認爲如果你三次調用這個方法,每個新的調用都不會取消前一個。所有onSuccess回調將在完成每個請求後觸發。例如,如果您將它稱爲2頁,然後是3,並且對2頁的請求將晚於3來完成。在用戶屏幕上,我們將看到2頁的結果。 – Nikolai

1

如果你想避免重複代碼,你可以做這樣的事情:

export class ListItemsComponent implements OnInit { 
    private _listItems = []; 
    page = 1; 
    constructor(private _listItemsService:ListItemsServiceService) { } 

    ngOnInit() { 
    this.pageChange(this.page); 
    } 

    subscription; 
    pageChange(page){ 
    if(this.subscription){ 
     this.subscribtion.unsubscribe(); 
    } 

    this.subscription = this._listItemsService.getListItems(this.page) 
     .subscribe(listItems => this._listItems = listItems); 
    } 
} 

如果你觀察到的總是使用相同的數據,你不希望在每個訂閱你需要的緩存添加到發送請求您觀察到的。例如:

this.yourObservable 
     .first() 
     .publishReplay(1) 
     .refCount(); 

更多的緩存位置:What is the correct way to share the result of an Angular 2 Http network call in RxJs 5?