最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Async pipe observable overwrite flashes the DOM - Stack Overflow

programmeradmin5浏览0评论

I am subscribing to an Observable in the DOM using the async pipe like so:

<div *ngIf="item$ | async as item; else loading">
    ....
    <div>{{item.name}}</div>
</div>

All is working fine.

However, I have a refresh method that the user can call and it will make the network request again, and return the item$ observable again.

So, in my ts controller:

this.item$ = this._itemService.getItem(url);

The item is mapped in the service.

But, I am setting item$ again. So while loading, the item in the DOM disappears as it does not exist anymore, and then will e back once the new $item is retrieved.

How do I "refresh" the $item without having item disappear in the DOM?

I am subscribing to an Observable in the DOM using the async pipe like so:

<div *ngIf="item$ | async as item; else loading">
    ....
    <div>{{item.name}}</div>
</div>

All is working fine.

However, I have a refresh method that the user can call and it will make the network request again, and return the item$ observable again.

So, in my ts controller:

this.item$ = this._itemService.getItem(url);

The item is mapped in the service.

But, I am setting item$ again. So while loading, the item in the DOM disappears as it does not exist anymore, and then will e back once the new $item is retrieved.

How do I "refresh" the $item without having item disappear in the DOM?

Share Improve this question asked Feb 26, 2018 at 22:28 PezetterPezetter 2,8622 gold badges24 silver badges41 bronze badges 5
  • Why do you replace the stream? Just send a new value into it, e.g. using a Subject. – jonrsharpe Commented Feb 26, 2018 at 22:33
  • Thats the answer i am looking for, not sure how to do it. – Pezetter Commented Feb 26, 2018 at 22:40
  • 1 I'd suggest starting with relevant RxJS docs. I wrote up one method I've used here: blog.jonrshar.pe/2017/Apr/09/async-angular-data.html – jonrsharpe Commented Feb 26, 2018 at 22:43
  • @jonrsharpe Thanks. I'll read up on that a bit more. Stuck on using a different method with a different http request. Subjects are pretty new to me. Any way to do this with my current setup? – Pezetter Commented Feb 26, 2018 at 23:35
  • 1 You'll have to change a few things; either have a Subject in your ponent, subscribe to your services calls manually and update it manually, or point item$ to a subject in your service that you push new values to when you call methods on it. – spongessuck Commented Feb 27, 2018 at 1:06
Add a ment  | 

1 Answer 1

Reset to default 7

As you said you override item$ and then it takes some time until it emits. So you can use a Subject instead and just make it call the this._itemService.getItem(url):

conts subject = new Subject<string>();

...

this.item$ = this.subject
  .switchMap(url => this._itemService.getItem(url));

Then you use it like you did with item$ | async. When you want to update the Observable you just emit a new URL to the Subject in your ponent:

this.subject.next(newUrl);

The async pipe will keep the original value displayed until getItem emits a new value but this way it won't blink.

发布评论

评论列表(0)

  1. 暂无评论