Как организовать службу Angular Data - PullRequest
0 голосов
/ 22 мая 2018

Я немного запутался из-за Наблюдаемых, Наблюдателей, Субъектов, Поведенческих Субъектов, Услуг, инъекций и т. Д.

Я пытаюсь сделать простое финансовое приложение.У меня есть служба транзакций, которая получает данные с сервера REST, а затем предоставляет их другим службам, которые могут обновить их, если это необходимо.Я могу получить компонент списка транзакций (который получает свои данные из getTransactions()) для обновления со службой, но я не знаю, как заставить компонент редактирования (который получает свои данные из "getTransaction(id)" для работы.

Как лучше всего разрешить компонентам воспроизводить данные из всего массива (доступ для чтения / записи), а также те, которые просто хотят воспроизвести с одним элементом массива?

Вотто, что у меня есть сейчас: (я изменил его на тонну, так что в настоящее время он сломан, но вы можете видеть, что я делал)

export class DataBrokerService {
  public transactions:Transaction[];

  constructor() {}

   ngOnInit(){
   }

  getTransactions(): Observable<Transaction[]>{
    if (needUpdate){
      // Download from REST API, subscribe result to transactions
      this.updateTransactions();
    }
    return of(this.transactions);
  }

  getTransaction(id:number): Observable <Transaction>{
    let transaction:Transaction;
    this.getTransactions().subscribe(txns => transaction = txns.find(txn => txn.id === id))
    });
    return transaction$;
  }

Я также сделал эту демонстрацию, демонстрирующую то, что я собираюсь: https://stackblitz.com/edit/angular-stackblitz-demo-dftmn3

Это следующий вопрос от: Получить одно значение из наблюдаемого массива

1 Ответ

0 голосов
/ 22 мая 2018

Хороший вопрос.Я знаю, что сначала сложно работать с RxJ, но когда вы освоите его, он станет достаточно мощным.

То, что вы хотите, может быть достигнуто с помощью BehaviorSubject.

Давайте найдемузнать, что такое Subject, и перейти на BehaviorSubject

Тема: является эквивалентом EventEmitter и единственным способом многоадресной передачи значения или события нескольким наблюдателям

Для получения дополнительной информации, посмотрите на здесь

Итак, мы знаем, что Subject похож на EventEmitter.Когда кто-то подписывается на него, каждый раз, когда вы звоните subject.next(value), каждый подписчик получает новое значение.Однако поздние подписчики (то есть подписка на Subject после вызова метода next) не получат предыдущие значения.Именно здесь BehaviorSubject появится на сцене.

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

export class DataBrokerService {
    // do not expose your subject to other classes
    private _transactions$: BehaviorSubject<Transaction[]> = new BehaviorSubject([]);
    // instead provide it as an observable
    public readonly transactions: Observable<Transaction[]> = this._transactions$.asObservable();

    needUpdate = true;

    constructor(private http: HttpClient) { }

    ngOnInit() {
    }

    // just return the observable
    getTransactions(): Observable<Transaction[]> {
        if (needUpdate) {
            this.updateTransactions();
        }
        return this.transactions;
    }

    // you can iterate over your transactions and filter them,
    // but DO NOT ever subscribe to it within a service. 
    // Otherwise, other classes won't be able to retrieve the value.
    getTransaction(id: number): Observable<Transaction> {
        return this.getTransactions().pipe(
            map(txns => txns.find(txn => txn.id === id))
        );
    }

    // when you need to update the transactions,
    // simply call this method
    updateTransactions() {
        this.http.get('transactions').subscribe(txns => {
            this.needUpdate = false;
            this._transactions$.next(txns);
        });
    }      
}
...