将对象转换为数组然后每隔几秒显示一个元素 更新 - 使用自定义运算符

问题描述

我像这样调用服务中的 API

getItems(): Observable<{}> {
    return this.http.get(<path>)
    .pipe(
      pluck('items'),);
  }

以这种形式返回数据:

items: Object { key: value,key: value,key: value ...}

我像这样在我的组件中订阅了这个

items$!: any;
constructor(private readonly service: Service) { }

  ngOnInit(): void {
    this.service.getItems().subscribe(items => this.items$ = items);
  }

并像这样在我的模板中显示它们

<div *ngFor="let item of items$ | keyvalue">
    <mat-card>
        <mat-card-header>
          {{item.key}}
        </mat-card-header>
        <mat-card-content>
          {{item.value}}
        </mat-card-content>
    </mat-card>
</div>

然而,我真正想要的是每隔几秒左右一次循环显示这些项目,而不是一次显示所有项目。我还想只进行一次 http 调用来完成此操作。我环顾四周,发现了解决方案的一些细节,但是,它通常至少涉及将对象转换为数组,然后可能使用某种 Subject 来观察订阅的原始 observable?这样做的干净方法是什么?谢谢。

解决方法

一种解决方案是将 API 中的数据转换为具有以下结构的数组:

const apiData = [{ a: 1 },{ b: 2 },{ c: 3 },{ d: 4 },{ e: 5 },{ f: 6 }];

接下来您可以使用以下使用 bufferCountconcatMapdelay 运算符的代码

data = [];

from(apiData)
  .pipe(
    bufferCount(1),concatMap(objs => of(objs).pipe(delay(3000)))
  )
  .subscribe(e => {
    this.data.push(e);
  });

在模板上

<div *ngFor="let item of data">
    {{item | json}}    <-- tweak around with it to get exact details you need -->
</div>
,

创建一个每 5 秒发出一个值并与所有订阅者共享相同值的流。


item$: Observable<Item>;

ngOnInit(): void { 
  this.item$ = this.service.getItems().pipe(
    switchMap(items => zip(
      from(items),timer(0,5000)
    )),map(([x,_]) => x),share()
  );
}

订阅流。异步管道是使用 angular 做到这一点的最佳方式

<div>
    <mat-card>
        <mat-card-header>
          {{(item$ | async).key}}
        </mat-card-header>
        <mat-card-content>
          {{(item$ | async).value}}
        </mat-card-content>
    </mat-card>
</div>

更新 - 使用自定义运算符

function intervalArray<T>(milliseconds = 1000): OperatorFunction<T[],T> {

  return s => s.pipe(
    concatMap((a: T[]) => zip(
      from(a),milliseconds)
    ).pipe(
      map(([x,_]) => x)
    ))
  );
  
}

ngOnInit(): void { 
  this.item$ = this.service.getItems().pipe(
    intervalArray(5000),share()
  );
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...