【问题标题】:Observable, async and other可观察,异步和其他
【发布时间】:2018-09-16 18:19:02
【问题描述】:

经过一整天的努力寻找合适的解决方案,我终于来这里寻求帮助了。

我需要什么 在服务中,我必须提供一个返回对象数组的函数;第一次使用 HttpClient 从 Web 服务中检索这些对象时,我想将它们存储在本地变量中,以避免每次调用此服务函数时都消耗时间和流量。
最后,我必须在 <select *ngFor 标记中显示这些对象,并在设置值后设置默认值。

第一次尝试

service.ts

  stati = null;

    getStati() {
      if (this.stati) return this.stati;
      return this.http.get<ApiResponse>(this.apiUrl + 'lists/stati')
        .pipe(
          retry(3),
          map(data => {
            if (data.status === 0)
              this.stati = data.response; // <-- this is an array
            return this.stati;
          }
      ));
    }

request.component.ts

this.svcApi.getStati()
  .subscribe((stati) => {
    this.stati = stati;
    this.request.nascita.stato = 'IT';
    this.request.residenza.stato = 'IT';
  });

request.component.html

<select class="form-control"
        [(ngModel)]="request.nascita.stato" name="stato">
  <option *ngFor="let stato of stati" 
      [value]="stato.codice">{{stato.nome | uppercase}}</option>
</select>

第一次有效,但是当我的路由器(重新)激活路由时,我在组件中收到一个错误,指出svcApi.getStati().subscribe 不是函数;我自然明白这一点,因为这次我不返回 Observable 而是返回一个数组!

第二次尝试
于是我尝试更改服务功能:
if (this.stati) return Observable.from(this.stati);

但是当我回到路线时,我在控制台中收到此错误:

错误错误:找不到不同的支持对象“[object Object]” '对象'类型。 NgFor 仅支持绑定到 Iterables,例如 数组。

第三次尝试
我最后一次尝试也是改变

<option *ngFor="let stato of stati | async"

但我收到此错误

错误类型错误:无法读取 null 的属性“处置” AsyncPipe.push

我很确定应该存在一个简单的解决方案,但作为一个新手我想不出来。

【问题讨论】:

  • 代替if (this.stati) return Observable.from(this.stati) 试试:if (this.stati) return Observable.of(this.stati)
  • @arturgrzesiak 你是我的救命稻草 :) 它有效,我觉得很愚蠢。太感谢了!请发表您的评论作为解决方案,我会接受!
  • 你为什么要手动存储响应?您可以使用基本的可观察函数更轻松地做到这一点。 learnrxjs.io/operators/multicasting/sharereplay.html
  • @appl3r 请注意,getStati 每次调用时都会返回一个新流,并且该流以 promise 开头 - 在这种情况下,.shareReplay(1).toPromise() 将非常等效。所以shareReplay如果不对服务做进一步的调整,也无济于事。

标签: angular typescript rxjs observable


【解决方案1】:

正如评论中提到的:

而不是 if (this.stati) return Observable.from(this.stati) try: if (this.stati) return Observable.of(this.stati)

感觉实际答案有点短,所以会提供更多上下文:

of(x) 等价于from([x])

of 基本上包装了传递给的任何内容而没有任何修改 - of(of) 是虚拟的,但完全没问题。另一方面,from 假定该值的类型为 ObservableInput&lt;T&gt; = SubscribableOrPromise&lt;T&gt; | ArrayLike&lt;T&gt; | Iterable&lt;T&gt;; 并将尝试将原始包装器转换为可观察对象。例如。 from(42) 不正确,但 from('42') 是 - 后者发出 42completesstring 确实是 ArrayLike,如果有人认为 from 的行为与 of 相同,这可能会让人感到困惑。 from 似乎有点过载 - 我个人从不使用 SubscribableOrPromise&lt;T&gt;

直观地说,from 可以很容易地解释为等价于of。恕我直言,应该有一个像 fromArray 这样的函数 - 特别是因为有 fromPromise 这几乎没有用,因为它不是懒惰的。在我的使用中,无论如何都会将数组传递给from

一些额外的反馈

如果getStati被多次调用,就会有多个请求到服务器并且缓存永不过期。

【讨论】:

  • 谢谢你的解释,现在我明白了!你是什​​么意思'在干净状态如果 getStati 多次调用会有多个服务器请求'?使用我提供的解决方案,不应该只向使用的服务器发出一个请求吗?下一个请求应该只使用内部数组...
  • 数组将被保存,但仅在第一次请求成功时。因此,在第一次调用和第一次成功之间的这个(可能)短暂间隔期间,多个调用将分别触发一个单独的请求。
猜你喜欢
  • 2019-01-11
  • 2018-04-18
  • 1970-01-01
  • 2019-12-31
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多