Angular2/4:实时刷新数据 [英] Angular2/4 : Refresh Data Realtime

查看:93
本文介绍了Angular2/4:实时刷新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要每隔一段时间刷新组件页面中的数据.另外,我需要在执行一些操作后刷新数据.我在服务中使用了Obeservables,因此我可以在响应准备就绪时进行订阅.我将订阅推送到一个对象,以便可以清除ngDestroy上的内容,我认为,可以通过以下方法实现相同的目的.

I need to refresh the data in a component page in an interval. Also I need to refresh the data after doing some action. I am using Obeservables in the service so that I can subscribe to when the response is ready. I am pushing the subscriptions to a object so that I can clear that on ngDestroy, I think, I have the following methods to achieve the same.

方法1:setInterval

我在ngOnInit上设置了一个间隔,它将以相等的间隔调用refreshData.间隔对象将使用ngOnDestroy方法中的clearInterval清除.

I have set an interval on ngOnInit, which will call the refreshData in equal interval. The interval object will be cleared using clearInterval in ngOnDestroy method.

export class MyComponent implements OnInit, OnDestroy {
    private subscription: Subscription = new Subscription();

    data: any;
    interval: any;

    ngOnInit() {
        this.refreshData();
        this.interval = setInterval(() => { 
            this.refreshData(); 
        }, 5000);
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
        clearInterval(this.interval);
    }

    refreshData(){
        this.subscription.add(
            this.myService.getData()
                .subscribe(data => {
                    this.data = data;
                })
        );
    }

    doAction(){
        this.subscription.add(
            this.myService.doAction()
                .subscribe(result => {
                    if(result === true){
                        this.refreshData();
                    }
                })
        );
    }
}

Q1:在每个刷新调用中,将向subscription对象添加订阅,这是否会增加内存使用率,并且如果用户保持打开页面一段时间,可能会导致浏览器崩溃?

Q1 : On each refresh call a subscription will be added to the subscription object, will that increase the memory usage and may crash the browser if user keeps the page opened for a while?

方法2:Observable.timer

此方法使用的计时器将在刷新数据后创建.

This method is using a timer which will created after the data is refreshed.

export class MyComponent implements OnInit, OnDestroy {
    private subscription: Subscription = new Subscription();

    data: any;

    ngOnInit() {
        this.refreshData();
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }

    refreshData(){
        this.subscription.add(
            this.myService.getData()
                .subscribe(data => {
                    this.data = data;
                    this.subscribeToData();
                })
        );
    }

    subscribeToData(){
        this.subscription.add(
            Observable.timer(10000).subscribe(() => this.refreshData())
        );
    }

    doAction(){
        this.subscription.add(
            this.myService.doAction()
                .subscribe(result => {
                    if(result === true){
                        this.refreshData();
                    }
                })
        );
    }
}

Q2:我在这里也有同样的问题(Q1).这样,会将计时器也添加到订阅对象中,因此实际上订阅对象中的订阅是原来的两倍.

Q2 : I have the same question(Q1) here. This way, will add the timers also to the subscription object, so infact the subscriptions in the subscription object is doubled.

Q3:要在操作方法-doAction()之后刷新数据,将调用refreshData.那会不会创建另一个计时器链?

Q3 : To refresh data after the action method - doAction(), the refreshData is called. So will that create another chain of timer?

Q4:哪种方法会更好,而不会导致内存泄漏或是否存在其他方法?

Q4 : Which is the better way without memory leaks or if there exists any other way?

推荐答案

您应该能够做到这一点而不会出现问题:

You should be able to do this without problems:

ngOnInit() {
    this.refreshData();
    this.interval = setInterval(() => { 
        this.refreshData(); 
    }, 5000);
}

refreshData(){
    this.myService.getData()
        .subscribe(data => {
            this.data = data;
        })
    );
}

根据这篇文章 Angular会照顾好自己的后尘.

As per this post Angular will take care of cleaning up after itself.

但是,如果您要在应用中拥有实时数据流,我建议您更改组件,以便您不必订阅服务的http请求的每个响应,而是订阅一次到组件的ngOnInit()中服务的新可观察到的data$属性.然后,按间隔(在执行操作时)在服务上调用updateData()(或在服务的内部间隔 中设置),但不进行订阅.当服务成功获取数据时,它将下一个值推入其可观察的data$属性,从而为您提供来自服务的数据流,您可以对应用程序中的任何位置进行响应.

However, if you're going to have a live data stream in your app I'd suggest changing your component so that rather than subscribing to each response of your service's http request, you instead subscribe once to a new observable data$ property of your service in your component's ngOnInit(). Then, on interval (as you're doing) call updateData() on your service (or setup the interval inside your service) but don't subscribe. When your service successfully fetches the data, it pushes the next value to its observable data$ property, giving you a stream of data from your service that you can react to anywhere in your app.

ngOnInit() {
    this.myService.data$.subscribe(data => { // subscribe once to the data stream
        this.data = data;
    })

    this.refreshData();
    this.interval = setInterval(() => { 
        this.refreshData(); 
    }, 5000);
}

refreshData(){
    this.myService.updateData(); // simply signal for the service to update its data stream
}

myService.data$是服务中更新的可观察到的BehaviourSubject,类似于以下内容:

With myService.data$ being an observable BehaviourSubject updated in your service, something like this:

public data$: BehaviorSubject<any> = new BehaviorSubject({});

updateData() {
    let data = this.http.get('http://www.data.com').map((data)=>{
        return data.json();
    }).do((data)=>{
        this.data$.next(data);
    })
}

这样,您可以避免多个预订,并使数据流可用于需要它的任何组件.

That way you can avoid multiple subscriptions and make the data stream available to any component that needs it.

这篇关于Angular2/4:实时刷新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆