【问题标题】:How to get actual value of observable如何获得可观察的实际值
【发布时间】:2019-02-12 18:56:31
【问题描述】:

在服务类中,方法必须传递当前设备序列号。使用 ngrx 可以订阅 device$ 以获得实际的设备,但这感觉不太好。这种情况的最佳做法是什么?

@Injectable()
export class DeviceService {
  public device$: Observable<Device>;
  public device: Device; // feels 'redundant'

  constructor(private http: HttpClient,
              private store: Store<DeviceState>,) {
    this.device$ = this.store.select(DeviceSelectors.getCurrentDevice);
    this.device$.subscribe((device: Device) => {
      this.device = device; // feels bad
    });
  }

  regenerate() : Observable<Object> {
    if (environment.production) {
      const url = `${environment.url}/devices/${this.device.serialNumber}/regenerate`;
      return this.http.get(url) as Observable<Object>;
    } else {
      return of({});
    }
  }
}

【问题讨论】:

  • 有什么问题?如果要在 html 中显示,可以使用异步管道。
  • 通常我将订阅移动到组件,在我看来,在服务中包含可观察值和原始值(内存中的重复变量)不是一个好习惯。
  • @EduardoVargas 这是一个服务类,所以没有显示在 html 中。感谢您的建议。
  • @Ricardo 我同意这不是一个好习惯。这就是我发布问题的原因:)。另一种选择确实是将设备从 html 传递给组件,将其分派给操作,在 ngrx/effects 中捕获它并将其传递给服务方法:(.
  • 可能使用switchMap?将第一个 http 调用的结果传递给第二个,所以一切都将驻留在 regenerate 方法中。 learnrxjs.io/operators/transformation/switchmap.html

标签: angular typescript ngrx rxjs6


【解决方案1】:

您可以使用 mergeMap 来实现您想要的:

@Injectable()
export class DeviceService {
    public device$: Observable<Device>;

    constructor(private http: HttpClient,
                private store: Store<DeviceState>,) {
        this.device$ = this.store.select(DeviceSelectors.getCurrentDevice);
    }

    regenerate() : Observable<Object> {
        if (environment.production) {
            return this.device$
                .pipe(
                    first(),
                    mergeMap(device => this.http.get(`${environment.url}/devices/${device.serialNumber}/regenerate`))
                );
        } else {
            return of({});
        }
    }
}

【讨论】:

    【解决方案2】:

    @NielsSteenbeek ,通常我所做的是即时从存储中获取值(当调用 regenerate() 时)你可以使用 flatMap 来归档你想要的

    @Injectable()
    export class DeviceService {
        constructor(private http: HttpClient, private store: Store<DeviceState>,) {}
    
        regenerate() : Observable<Object> {
            if (environment.production) {
                return this.store.select(DeviceSelectors.getCurrentDevice)
                    .pipe(
                        first(),
                        flatMap(device => this.http.get(`${environment.url}/devices/${device.serialNumber}/regenerate`))
                    );
            } else {
                return of({});
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-18
      • 2016-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多