簡體   English   中英

在 ngrx/data 中使用存儲值

[英]Use store values in ngrx/data

我正在使用ngrx/data,我需要做的是在商店中設置一個值,我們稱之為ID。 然后當我向實體發出任何請求以從商店中提取該 ID 時。 我將以update為例。

這是客戶端實體服務的示例。 我可以很容易地 map 將返回的數據作為super.update返回一個 observable。

import { Injectable } from '@angular/core';
import { EntityCollectionServiceBase, EntityCollectionServiceElementsFactory } from '@ngrx/data';
import { Client } from '../../store/client/client.model';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ClientEntityService extends EntityCollectionServiceBase<Client> {

  constructor(
    serviceElementsFactory: EntityCollectionServiceElementsFactory,
  ) {
    super('Client', serviceElementsFactory);
  }

  public update(entity: Partial<Client>): Observable<Client> {
    return super.update(entity);
  }

}

但是我想使用存儲值進行更新。 所以專注於update我可以這樣做:

public update(entity: Partial<Client>): Observable<Client> {
    this.store.pipe(
      tap((store) => {
        console.log(store);
      })
    ).subscribe();
    return super.update(entity);
  }

哪個打印出商店,我可以看到我需要的價值,所以我可以這樣做

public update(update: Partial<Client>): Observable<Client> {
    return this.store.pipe(
      select(getClientId),
      take(1)
    ).subscribe((id) => {
      return super.update({
        id,
        ...update
      });
    });
  }

但是,它要求我訂閱 observable 才能觸發它。 那將意味着調用者無法 pipe 結果並且通常不理想。

我想知道是否有人知道能夠從商店獲取數據但不必像我在上面那樣訂閱以獲取數據的好解決方案,理想情況下我想使用這樣的switchMap

  public update(update: Partial<Client>): Observable<Client> {
    return this.store.pipe(
      select(getClientId),
      switchMap((id) => {
        return super.update({
          id,
          ...update
        });
      }),
      take(1)
    )

謝謝

您在理想的解決方案中正確地編寫了它。 不同之處在於您只需將 take(1) 移動到 select 之后。

public update(update: Partial<Client>): Observable<Client> {
    return this.store.pipe(
      select(getClientId),
      take(1),
      switchMap((id) => {
        return super.update({
          id,
          ...update
        });
      }),
    )

因此 store 不會在每次更改時都導致update請求。

進入super.update調用后,我可以看到調度程序正在調用:

update(entity, options) {
        // update entity might be a partial of T but must at least have its key.
        // pass the Update<T> structure as the payload
        /** @type {?} */
        const update = this.toUpdate(entity);
        options = this.setSaveEntityActionOptions(options, this.defaultDispatcherOptions.optimisticUpdate);
        /** @type {?} */
        const action = this.createEntityAction(EntityOp.SAVE_UPDATE_ONE, update, options);
        if (options.isOptimistic) {
            this.guard.mustBeUpdate(action);
        }
        this.dispatch(action);
        return this.getResponseData$(options.correlationId).pipe(
        // Use the update entity data id to get the entity from the collection
        // as might be different from the entity returned from the server
        // because the id changed or there are unsaved changes.
        map((/**
         * @param {?} updateData
         * @return {?}
         */
        updateData => updateData.changes)), withLatestFrom(this.entityCollection$), map((/**
         * @param {?} __0
         * @return {?}
         */
        ([e, collection]) => (/** @type {?} */ (collection.entities[this.selectId((/** @type {?} */ (e)))])))), shareReplay(1));
    }

它實際上只是調度了一些動作,然后使用相關 ID 等從this.getResponseData$創建一個選定的可觀察對象。

在我的用例中,因為我使用商店來獲取當前客戶端的 Id,所以我不需要返回更新的客戶端,因為我已經有一個 observable。

ClientEntityService之上,我有另一個門面,我稱之為ClientService

看起來像這樣:

@Injectable({
  providedIn: 'root'
})
export class ClientService {
  constructor(
    private clientEntityService: ClientEntityService,
    private store: Store<AppState>
  ) {}

  public getCurrentClient(): Observable<Client> {
    return this.clientEntityService.entityMap$.pipe(
      withLatestFrom(this.store.pipe(select(getCurrentId))),
      map(([clients, currentId]) => clients[currentId])
    );
  }

  public updateCurrentClient(update: Partial<Client>): Subscription {
    return this.getCurrentClient().pipe(
      take(1),
      switchMap((client) => {
        return this.clientEntityService.update({
          id: client.id,
          ...update
        });
      })
    ).subscribe();

  }
}

所以現在從我的組件中我有了構造函數

constructor(
    private clientService: ClientService,
  ) {
    this.client$ = this.clientService.getCurrentClient();
  }

然后在更新時我打電話:

this.clientService.updateCurrentClient(theUpdate);

而且因為我已經將this.client$作為正在更新的客戶端的可觀察對象,所以我不需要updateCurrentClient來返回Observable<Client> 所以如上所述,我只是返回Subscription

可以修改updateCurrentClient以實現類似於 DefaultDataService 返回的內容,但我希望在未來的版本中可能會發生變化。 所以現在。 我對這個解決方案很滿意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM