Javascript-форум (https://javascript.ru/forum/)
-   Angular.js (https://javascript.ru/forum/angular/)
-   -   Подчитывание данных в компонент по HTTP (https://javascript.ru/forum/angular/74372-podchityvanie-dannykh-v-komponent-po-http.html)

sniffysko 04.07.2018 17:39

Подчитывание данных в компонент по HTTP
 
В компонент подгружаются данные. Поскольку данных много, читаем их по частям. К компоненту подключен сервис, который читает данные. Если читать одним куском -- нет вопросов. А вот как быть с чтением кусками?
// массив данных
public userReqList: AssessRequest[];

// сервис работы с данными
constructor(
	private reqListService: RequestListService,
) {}

// во время инициализации читаем стартовую порцию данных
ngOnInit() {
	const url = `${this.apiRoute}`;
	this.listSubscr$ = this.reqListService
		.getUserReqList(url)
		.subscribe((data: AssessRequest[]) => {
			this.userReqList = data;
		});
}

// закрываем подписку на поток данных
ngOnDestroy(){
	this.listSubscr$.unsubscribe();
}

// Событие скролла, которое инициируем подчитывание данных
onScrollDown(): void {
	this.readItems(this.userReqList.length, this.limit, this.filter);
}

// Подчитываем данные по кусочку, указывая считываемый фрагмент
readItems(from: number, limit: number): void {
	const url = `${this.apiRoute}?start=${from}&limit=${limit}`;
	
	this.reqListService
		.getUserReqList(url)
		.subscribe((data) => {
			this.userReqList.push(...data);
		})
}


По идее каждый вызов readItems будет генерировать подписку на поток, которая после прочтения потока как бы зависает в воздухе и формирует куче слушателей.

Как обойти такое? Можно конечно сразу-же по завершению потока отписываться от него, но это, по моему, как-то ненормально.

readItems(from: number, limit: number, filter: string): void {
	const url = `${this.apiRoute}?start=${from}&limit=${limit}`;
	const subscr$ = this.reqListService
		.getUserReqList(url)
		.subscribe((data) => {
			this.userReqList.push(...data);
			subscr$.unsubscribe();
		})
}


Есть же наверное стандартный подход для такой ситуации?
Я искал решения, но подходящего не нашел.
Буду благодарен за помощь.

destus 05.07.2018 07:25

sniffysko,
Используй take(1), который автоматически выполнит отписку после получения данных https://www.learnrxjs.io/operators/filtering/take.html

sniffysko 06.07.2018 13:16

take(1) предполагает чтение 1 записи из потока. Я не знаю изначально сколько данных придет.
А вот здесь: Отписываться или не отписываться пишут, что описку от потоков http производить не надо. Может я неправильно понял?

destus 06.07.2018 15:10

sniffysko,
Так у вас при скролле вызывается метод readItems, в котором и происходит подписка. Если вы в этот метод добавите take(1), то при получении данных будет сразу и отписка. При следующем скролле - новая подписка => получение данных => отписка и т.д.
Цитата:

А вот здесь: Отписываться или не отписываться пишут, что описку от потоков http производить не надо
Да https://github.com/angular/angular/b...rc/xhr.ts#L217


Часовой пояс GMT +3, время: 03:21.