Обновить наблюдаемые данные, когда пользователь нажимает кнопку - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть компонент Angular 6, где у меня есть сетка, которая использует асинхронный канал для подписки на наблюдаемые элементы. Я хотел бы иметь кнопку, которая при нажатии обновляет данные в этой наблюдаемой. Я добавил следующий код:

public refreshData(): void {
   this.details$ = this._service.getDetails();
}

Тогда по шаблону:

*ngIf="(details$ | async); let d"

Так что сейчас, каждый раз, когда пользователь нажимает кнопку, выполняется метод refreshData. Этот код работает, данные обновляются, но я создаю новую наблюдаемую для каждого клика. Есть ли лучший способ справиться с этим?

Ответы [ 3 ]

2 голосов
/ 02 апреля 2019

Как прокомментировано, более реактивный способ сделать это будет следующим:

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();
  }
}
0 голосов
/ 02 апреля 2019

Я не уверен, какова ваша цель. Обновлять данные в представлении только при нажатии кнопки, даже когда служба тем временем предоставила свежие данные, или добавить в поток некоторые совершенно новые данные объекта при нажатии кнопки, но представление должно постоянно обновлять сведения о них исходя из сервиса или нажатия кнопки. Предположим второй случай на данный момент:

Для управления потоком потока, то есть для возможности добавления в поток, вы можете использовать Subject.

Местный субъект

Предполагая, что вы не хотите трогать логику _service и вам нужно только обновленное значение внутри вашего компонента, но вы все равно получаете входные данные от его getDetails() наблюдаемого: вы можете подписаться на услугу в своем ngOnInit , передавая результат вашему локальному Subject, а также передавая обновленное значение в ваш метод refreshData(). Предполагая, что тип деталей равен Details, мы получаем:

private details$: Subject<Details>;

constructor(private _service: Service) {}

ngOnInit(): void {
  this._service.getDetails().subscribe(updateDetails => this.details$.next(updateDetails));
}

ngOnDestroy(): void {
   this.details$.complete();
}

public refreshData(): void {
  this.details$.next(new Details());
}

Служебная тема

Если вы хотите сохранить обновление не только локально, но и отправить его в службу, вам необходимо настроить логику службы для обработки обновления данных. Это означает превращение наблюдаемой услуги в Subject. Обычно вы не хотите напрямую раскрывать субъекты служб, а только наблюдаемую сторону субъекта и обрабатывать запросы на обновление в методе. Это значит в вашем сервисе:

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

public getDetails(): Observable<Details> {
   return this._details$;
}

public updateDetails(update: Details): void {
   // you can add some check logic if the update is valid here
   this._detailsSource$.next(update);
}

А в вашем компоненте вам просто нужно настроить метод обновления:

refreshData(): void {
  this._service.updateDetails(new Details());
}

Вы также можете пропустить метод getDetails в своем сервисе и просто предоставить подробности, которые можно наблюдать непосредственно, сделав его общедоступным:

private _detailsSource$: Subject<Details> = new Subject<Details>();
public details$: Observable<Details> = this._detailsSource$.asObservable();
0 голосов
/ 02 апреля 2019

Попробуйте использовать тему, и каждый раз, когда вы хотите обновить данные, просто обновите тему, это будет отражено в пользовательском интерфейсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...