Как перебрать RX JS наблюдаемый массив объектов [{}, {} ...] в Angular 8+ и pu sh свойств каждого объекта в шаблоне по одному объекту за раз - PullRequest
0 голосов
/ 28 апреля 2020

Цель состоит в том, чтобы проанализировать наблюдаемый массив из 10 объектов, которые содержат HTML свойства привязки и pu sh их по одному объекту за раз (id, url, title), чтобы заполнить анимированный шаблон, затем следующий объект.

Я вытягиваю массив JSON (JSON .stringify ({results})) из функции AWS Lambda через AWS API Gateway через HTTPClient Angular.

Объект Array выглядит следующим образом:

```
{
results: [{id: any, url: 'string', title: 'string'}, {id: any, url: 'string', title: 
'string'},...}]
}

The Template Looks Like This:

    ```
    <div class="primary" #elmRef>
      <div class="secondary" *ngFor="let anchor of (this.newsObj$ | async)" id="{{anchor.id}}">
        <a href="{{anchor.url}}">{{anchor.title}}</a>
      </div>
    </div>

Схема / Модель / Интерфейс выглядит следующим образом:

export interface Nstream {
      id: any;
      title: string;
      link: string;
}

Это служба API:

loadAllNews$(): Observable<Nstream[]> {
  return this.http.get<Nstream[]>('https://example.com/stage/{proxy+}')
    .pipe(
      map(response => response['results']),
      shareReplay());
}

Это компонент:

export class NewsStreamComponent implements OnInit, AfterViewInit {


  private subject = new BehaviorSubject<Nstream[]>([]);  // remembers the last array obj it emitted
  newsObjs$ = this.subject.asObservable();
  @ViewChild('elmRef', {static: false}) elmRef;

  constructor(private api: ApiService) { }

  obj$: Observable<any>;


  // onAnimationStart(event) {---TBD---}
  // onAnimationEnd(event) {---TBD---}

ngOnInit() {
    this.newsObjs$ = this.api.loadAllNews$()
      .pipe(
        map((response) => response));
  }

//  This is where I left off
ngAfterViewInit() {
  this.obj$ = this.newObjs$.pipe(
    switchMap(response => response),
      map(values => values),
    take(1));
  }
// this.obj$.subscribe(v => console.log('first instance of endpoint from object obj$: ',  v));
}

ПОЖАЛУЙСТА, ОБРАТИТЕ ВНИМАНИЕ: меня больше всего волнует, как итерировать и заполнять шаблон в данный момент. Я расскажу об анимации позже, так как предоставил ее только для обеспечения некоторого контекста.

В настоящее время: я могу заполнить шаблон, однако, только внутри функции ngOnInit и со всеми 10 объектами, сложенными друг на друга что я и хочу (думаю). Я выбрал этот подход, предполагая, что смогу перебирать идентификаторы объектов, всплывать и использовать его для переключения ngIf в шаблоне, таким образом показывая только шаблон с соответствующими идентификаторами в ngAfterViewInit (). После нескольких часов попыток поиска я бросаю полотенце и ищу помощи. Заранее благодарю за любую помощь, которую вы можете оказать.

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

чуть меньше ручной сборки этой функциональности, если это то, что вам нужно:

this.newsObjs$ = this.api.loadAllNews$().pipe(
  switchMap(values => from(values)),
  concatMap(value => timer(500).pipe(mapTo(value)))
)

или

this.newsObjs$ = this.api.loadAllNews$().pipe(
  switchMap(values => from(values)),
  concatMap(value => of(value).pipe(delay(500)))
)

обе функции одинаковы. нет разницы между ними. может также выполнить это с помощью switchMap в concat массива, сопоставленного с теми же наблюдаемыми внутри операторов concatMap выше

1 голос
/ 28 апреля 2020

Ну, вы можете сделать это:

ngOnInit() {
  // this will emit an observable each 500ms
  this.newsObjs$ = this.api.loadAllNews$().pipe(
    switchMap((values) => new Observable(observer => {
      if(!(values && values.length)) {
        observer.complete();
      }

      let index = 0;
      const interval = setInterval(() => {
        if(index < values.length) {
          observer.next(values[index++]);
        } else {
          observer.complete();
          clearInterval(interval);
        }
      }, 500);
    }))
  );
}

Но почему бы вам не использовать пошаговую анимацию ? Он запекается внутри @ angular / animations.

...