[英]How can I subscribe or merge new Observable in RXJS and Angular
I have a service that always returns Observable<T>
, and I cannot change the code of this service.我有一个总是返回
Observable<T>
的服务,我无法更改该服务的代码。
Supposed I have a button, whenever the button is clicked, I call the method in the service, and it returns a new Observable.假设我有一个按钮,每当单击该按钮时,我都会调用服务中的方法,它会返回一个新的 Observable。 How can I update the new data to UI?
如何将新数据更新到 UI?
Source code and playground on StackBlitz StackBlitz 上的源代码和游乐场
app.component.ts
import { Component, Injectable, OnInit } from '@angular/core';
import { Observable, of } from 'rxjs';
@Injectable()
export class Service {
// Cannot change the code in this class
public getRandom(): Observable<number> {
return of(Math.random());
}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit {
constructor(private service: Service) {}
public random: number = 0;
public random$: Observable<number> = new Observable<number>();
ngOnInit(): void {
this.random = 0;
}
buttonClick(): void {
// how can I update the random with this.service.getRandom()?
console.log('button clicked')
}
}
app.component.html
<h1>{{random}}</h1>
<button (click)="buttonClick()">Get new Random number</button>
I highly recommend using the reactive approach:我强烈建议使用反应式方法:
HTML HTML
<ng-container *ngIf="(random$ | async) as theRandomNumber" >
<h1>{{ theRandomNumber }}</h1>
</ng-container>
<button (click)="buttonClick()">Get new Random number</button>
ts TS
export class AppComponent implements OnInit {
random$: Observable<number>!; // no need to initialize it
constructor(private service: Service) {}
ngOnInit(): void {}
buttonClick(): void {
this.random$ = this.service.getRandom();
}
}
When you trigger the event click
, your public class property random$
will store the observable
from your service, then, within your template html, using the async
pipe, you subscribe to random$
, and it will react for every click
event, with this, you keep your ts file cleaner and simple当您触发事件
click
时,您的公共 class 属性random$
将存储来自您的服务的observable
对象,然后,在您的模板 html 中,使用async
pipe,您订阅random$
,它将对每个click
事件做出反应,与此,你让你的 ts 文件更干净简单
Now, if for some reason, you need to have that random number within your ts
file, you could pipe
the observable
and still keep this reactive approach:现在,如果出于某种原因,您需要在
ts
文件中包含该随机数,您可以pipe
observable
并仍然保持这种反应式方法:
import { tap } from 'rxjs';
export class AppComponent implements OnInit {
random$: Observable<number>!; // no need to initialize it
private random!: number;
constructor(private service: Service) {}
ngOnInit(): void {}
buttonClick(): void {
this.random$ = this.service.getRandom()
.pipe(tap((theNumber) => this.random = theNumber));
}
}
One easy way is to convert the Observable to a Promise and use await:一种简单的方法是将 Observable 转换为 Promise 并使用 await:
async buttonClick(): Promise<void> {
const value = await firstValueFrom(random$);
console.log('button clicked ' + value);
}
If the Observable emits more than once and you want all values, use.subscribe().如果 Observable 发射不止一次并且你想要所有的值,使用.subscribe()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.