Angular 当用户单击按钮时刷新可观察数据

Angular 当用户单击按钮时刷新可观察数据,angular,rxjs,Angular,Rxjs,我有一个Angular 6组件,其中我有一个网格,它使用异步管道订阅带有项目的可观测数据。我想有一个按钮,当点击时,刷新该可观察数据。我添加了以下代码: public refreshData(): void { this.details$ = this._service.getDetails(); } 然后,在模板上: *ngIf="(details$ | async); let d" 所以现在,每当用户单击按钮时,就会执行refreshData方法。这段代码工作正常,数据被刷新,但我

我有一个Angular 6组件,其中我有一个网格,它使用异步管道订阅带有项目的可观测数据。我想有一个按钮,当点击时,刷新该可观察数据。我添加了以下代码:

public refreshData(): void {
   this.details$ = this._service.getDetails();
}
然后,在模板上:

*ngIf="(details$ | async); let d"
所以现在,每当用户单击按钮时,就会执行refreshData方法。这段代码工作正常,数据被刷新,但我正在为每次点击创建一个新的可观察对象。
有更好的处理方法吗?

尝试使用主题,每次您想要更新数据时,只要更新主题,它就会反映在ui中。

尝试使用主题,每次您想要更新数据时,只要更新主题,它就会反映在ui中。

如评论所示,一种更具反应性的方法是:

import {Subject,Observable} from 'rxjs';
import {startWith,switchMap} from 'rxjs/operators';

class FooComponent implements OnDestroy {
  private readonly refreshClick$ = new Subject<void>();
  readonly details$ : Observable<FooDetails>;

  constructor(...){
    this.details$ = this.refreshClick$.pipe(
     // fake emission of a click so that initial data can be loaded
     startWith(undefined),
     switchMap(() => this._service.getDetails())
    );
  }

  ngOnDestroy(){
    // "complete" should be invoked on subjects once their lifetime is complete
    refreshClick$.complete();
  }

  refresh(){
    this.refreshClick$.next();
  }
}

如前所述,一种更具反应性的方法是:

import {Subject,Observable} from 'rxjs';
import {startWith,switchMap} from 'rxjs/operators';

class FooComponent implements OnDestroy {
  private readonly refreshClick$ = new Subject<void>();
  readonly details$ : Observable<FooDetails>;

  constructor(...){
    this.details$ = this.refreshClick$.pipe(
     // fake emission of a click so that initial data can be loaded
     startWith(undefined),
     switchMap(() => this._service.getDetails())
    );
  }

  ngOnDestroy(){
    // "complete" should be invoked on subjects once their lifetime is complete
    refreshClick$.complete();
  }

  refresh(){
    this.refreshClick$.next();
  }
}

我不确定你的目标是什么。仅在单击按钮时更新视图中的数据,即使服务同时提供了新数据,或在单击按钮时向流中添加一些全新的详细信息对象,但视图应不断更新来自服务或单击按钮的详细信息。现在假设第二种情况:

要控制流的流,即能够添加到流,可以使用主题

本地科目 假设您不想接触_服务逻辑,只需要组件中的刷新值,但仍然从其getDetails observable获取输入:您可以在ngOnInit中订阅服务,将结果传递给本地主体,并在refreshData方法中传递刷新值。假设详细信息类型为我们获得的详细信息:

在组件中,您只需调整刷新方法:

refreshData(): void {
  this._service.updateDetails(new Details());
}
您还可以跳过服务中的getDetails方法,只需公开可观察到的细节:

private _detailsSource$: Subject<Details> = new Subject<Details>();
public details$: Observable<Details> = this._detailsSource$.asObservable();

我不确定你的目标是什么。仅在单击按钮时更新视图中的数据,即使服务同时提供了新数据,或在单击按钮时向流中添加一些全新的详细信息对象,但视图应不断更新来自服务或单击按钮的详细信息。现在假设第二种情况:

要控制流的流,即能够添加到流,可以使用主题

本地科目 假设您不想接触_服务逻辑,只需要组件中的刷新值,但仍然从其getDetails observable获取输入:您可以在ngOnInit中订阅服务,将结果传递给本地主体,并在refreshData方法中传递刷新值。假设详细信息类型为我们获得的详细信息:

在组件中,您只需调整刷新方法:

refreshData(): void {
  this._service.updateDetails(new Details());
}
您还可以跳过服务中的getDetails方法,只需公开可观察到的细节:

private _detailsSource$: Subject<Details> = new Subject<Details>();
public details$: Observable<Details> = this._detailsSource$.asObservable();

您是否考虑过使用主题,以便可以将新项目添加到同一个流中?与替换引用相比,更新/添加到流中没有任何好处-因此,除非您有特定的要求,否则我会说保持原样。在类中创建BehavivorSubject。您的函数应该只向其中推送新数据。我担心的情况是,使用当前的解决方案,我不会从流订阅。因此,当我在refreshData方法中创建一个新的observable时,async管道是否从旧的订阅中订阅?从组件方面来说,您无法做任何事情,要将新数据推送到订阅方,您必须在服务中实现逻辑。关于你的第二条评论,使用async automatically unsubscribe on Destroyment从视图订阅。你有没有考虑过使用主题,以便可以将新项目添加到同一个流中?我看不到更新/添加到流中比替换引用有任何好处-因此,除非你有特定要求,我想让它保持原样。在类中创建一个主题。您的函数应该只向其中推送新数据。我担心的情况是,使用当前的解决方案,我不会从流订阅。因此,当我在refreshData方法中创建一个新的observable时,async管道是否从旧的订阅中订阅?从组件方面来说,您无法做任何事情,要将新数据推送到订阅方,您必须在服务中实现逻辑。对于您的第二条评论,使用async从视图订阅在Destroy上自动取消订阅,我已经应用了该解决方案,效果非常好。谢谢您可以使用private readonly refreshClick$=new Behavior SubjectNull;它在初始化时发出。那么你就不需要StarTwithUndefine的假发射了,我已经应用了这个解决方案,并且工作得非常完美。谢谢您可以使用private readonly refreshClick$=new Behavior SubjectNull;它在初始化时发出。那你就不需要了 d用StartTwithUndefined伪造排放物