2017-02-16 3 views
1

У меня есть служба, которая предоставляет мне возможность наблюдать через запрос на получение http и следующую операцию с картой. В моем компоненте я подписываюсь на наблюдаемый в методе ngOnInit. Поскольку у меня есть функциональность разбиения на страницы, я хотел бы запустить другой запрос службы, когда пользователь нажимает на другую страницу страницы. Как я могу это достичь? Должен ли я снова подписываться на услугу в новом методе или можно инициализировать наблюдаемый внутри компонента, чтобы я мог использовать его любым способом?Угловой запрос на 2 секунды для наблюдения

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, вызовите pageChange метод ListItemsService whcich в свою очередь, вызывает событие ListItems $.

+0

Мне нравится ваш подход. У меня вопрос, что произойдет, если пользователь откроет одну страницу и сразу откроет другую. И первый запрос будет завершен позже второго по некоторым причинам. Вы знаете какой-либо метод rxjs для «забывания» предыдущего запроса? – Nikolai

+0

Это определение наблюдаемого, разве это не так? Наблюдаемый останавливает один запрос, когда другой уволен. – MeMeMax

+0

'pageChange (страницы) { this.http.get (this.baseUrl + page.id) .subscribe (пункты => { this.dataStore.listItems = предметы; this._listItems.next (предметы); }); } ' Я думаю, что если вы вызовете этот метод 3 раза, каждый новый вызов не отменяет предыдущий. И все обратные вызовы 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?

Смежные вопросы