angular - 如何在 Angular 8+ 中迭代 RXJS 可观察对象数组 [{},{}...] 并将每个对象的属性一次推送到模板一个对象
问题描述
目标是解析一个包含 10 个对象的可观察数组,其中包含 HTML 锚属性,并一次推送一个对象(id、url、title),以填充动画模板,然后是下一个对象。
我通过 Angular 的 HTTPClient 通过 AWS API 网关从 AWS Lambda 函数中提取 JSON 数组 (JSON.stringify({results}))。
数组对象如下所示:
```
{
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 个对象都堆叠在一起,这就是我想要的(我认为)。我采用了这种方法,假设我能够遍历对象的 id,呈现一个,并使用它来切换模板上的 ngIf,从而仅在 ngAfterViewInit() 中显示具有匹配 id 的模板。经过几个多小时的尝试和搜索,我认输并寻求帮助。提前感谢您提供的任何帮助。
解决方案
好吧,你可以这样做:
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 中烘焙。
推荐阅读
- python - 如何更改我的 requests.get() 函数的发送方式?
- php - 我的网站总是内存不足(致命错误)
- vue.js - 在 bootstrap-vue 中折叠时如何隐藏导航栏
- python - 在 Python 中使用过滤器从文本文件中过滤行
- swift - 核心数据:ID 已设置,但保存时显示为 nil
- laravel - 在控制器内部的 Laravel 中使用 Summer Note 文本编辑器时如何将 base64 图像转换为 Url 图像?
- spring-boot - 未经授权的错误:访问此资源需要完全身份验证
- blazor - 在通过 Http.GetStringAsync 使用 IP 访问的“本地模式”下将 Blazor WebAssembly 与 Azure 函数一起使用时,我收到“无法获取错误”
- python - 在熊猫中将月份从数字重命名为名称
- flutter - RedirectException:检测到重定向循环