it-swarm.com.ru

Angular 6 задержать цикл

У меня есть вопрос о петлях angular. Я хотел бы отложить процесс рендеринга на нг-для. Например,

<div *ngFor="let data of items | delay">
  <app-my-component [data]="data"></app-my-component>
</div>

Задержка 10 мс для каждого рендера. Массив "items" происходит из другого компонента, который я не могу изменить. Кроме того, размер массива "items" может быть увеличен или уменьшен. Может быть, я могу перенаправить его с помощью наблюдаемой структуры. Я пытался наблюдать с асинхронным, но не могу достичь. Может кто-нибудь показать мне пример?

4
alim

На самом деле это интересный вопрос, и не удалось найти точный вопрос на SO.

Это мое решение, я написал вспомогательные методы для облегчения понимания и повторного использования кода в будущем:

Мое решение на Live StackBlitz редактор Ссылка

import { from, timer, Observable } from 'rxjs';
import {
  scan,
  map,
  concatMap,
  share,
} from 'rxjs/operators';

const timeOf = (interval: number) => <T>(val: T) =>
  timer(interval).pipe(map(x => val));

const timed = (interval: number) => <T>(source: Observable<T>) =>
  source.pipe(
    concatMap(timeOf(1000)),
    map(x => [x]),
    scan((acc, val) => [...acc, ...val]),
  )

И использование:

  arr = [1, 2, 3, 4, 5]

  arr$ = from(this.arr)
    .pipe(
      timed(1000),
    )

Что касается HTML будет:

<div *ngFor="let i of arr$ | async">
    <b>{{ i }}</b>
</div>

Что касается объяснения:

from(this.arr) будет генерировать каждый из элементов массива отдельно, а затем я использую concatMap() для каждого испускаемого элемента в timer(1000), что существенно задерживает каждый испускаемый элемент на 1 секунду. Наконец, я использую оператор scan() для объединения каждого испускаемого элемента обратно в окончательный накопленный массив.

2
Goga Koreli

Вы можете использовать асинхронный канал для загрузки наблюдаемого

//define your delay observable
this.delayItems=of(items).pipe(delay(1000))

в вашем шаблоне 

<div *ngFor="let data of delayItems | async">
  <app-my-component [data]="data"></app-my-component>
</div>

Обновление

import { Component } from '@angular/core';
import { from, timer, Observable } from 'rxjs';
@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  arr = [1, 2, 3, 4, 5]
  arr$:Observable<any[]>
  constructor() {
    this.arr$=from(this.arr).pipe(
    concatMap(item=>timer(1000).pipe(mapTo(item))),
    scan((acc,curr:number)=>acc.concat(curr),[])
  )

  }
}

hTML

<div *ngFor="let i of arr$ | async">
    <b>{{ i }}</b>
</div>
1
Fan Cheung