Angular2/4: 实时刷新数据

19 浏览
0 Comments

Angular2/4: 实时刷新数据

我需要在一个组件页面上定期刷新数据。同时,在执行某些操作后,我也需要刷新数据。我在服务中使用Observables,这样我就可以在响应准备好时订阅它们。我将订阅对象添加到一个对象中,这样我可以在ngDestroy中清除它,我认为我有以下几种方法来实现同样的效果。\n方法一:setInterval\n我在ngOnInit中设置了一个定时器,它将以相等的间隔调用refreshData方法。该定时器对象将在ngOnDestroy方法中使用clearInterval清除。\n

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();
                    }
                })
        );
    }
}

\n问题1:在每次刷新调用时,会将一个订阅添加到subscription对象中,这会增加内存使用量并可能导致浏览器在用户长时间保持页面打开时崩溃吗?\n方法二:Observable.timer\n这种方法是在数据刷新后创建一个定时器。\n

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();
                    }
                })
        );
    }
}

\n问题2:我在这里也有同样的问题(问题1)。这种方式会将定时器也添加到subscription对象中,实际上subscription对象中的订阅数量翻倍。\n问题3:在执行操作方法doAction()后刷新数据,会调用refreshData()。那么这会创建另一个定时器链吗?\n问题4:哪种方法更好,没有内存泄漏,或者是否存在其他方法?

0
0 Comments

Angular2/4 : 刷新实时数据的问题出现的原因是没有在ngDestroy中清除定时器。解决方法是在ngDestroy中添加清除定时器的代码。

在Angular中,组件有生命周期钩子函数,可以在特定的生命周期阶段执行一些操作。ngDestroy是组件被销毁之前的最后一个生命周期钩子函数。

在给定的代码示例中,ngDestroy函数中使用了clearInterval函数来清除定时器。clearInterval函数用于取消由setInterval函数设置的定时器。通过将clearInterval函数放在ngDestroy函数中,可以确保在组件销毁时清除定时器,以避免内存泄漏和其他问题。

另外,在ngDestroy函数中还使用了this.unsubscribe.next()和this.unsubscribe.complete()。这是为了清除可能存在的订阅,以避免内存泄漏和其他问题。

总结起来,解决Angular2/4刷新实时数据的问题的方法是在ngDestroy函数中添加清除定时器和订阅的代码。

更多关于Angular生命周期钩子函数的信息可以查看angular.io/guide/lifecycle-hooks

0
0 Comments

Angular2/4 : 刷新实时数据

问题原因:

在Angular应用中,当需要实时刷新数据时,通常会使用定时器来定期调用数据更新的方法。然而,当订阅数据时,每次调用都会创建一个新的订阅,导致内存泄漏和性能问题。

解决方法:

为了解决上述问题,可以使用RxJS库中的Subject和takeUntil操作符。Subject是一个可观察对象,可以用来发送和订阅数据。takeUntil操作符用于在指定的条件满足时终止订阅。

首先,在组件中引入Subject并创建一个私有的Subject对象`unsubscribe`。在组件的`ngOnInit`方法中,订阅`myService`中的`data$`流,并在接收到数据时更新组件的`data`属性。同时,使用定时器定期调用`refreshData`方法来更新数据。在组件的`ngOnDestroy`方法中,通过调用`unsubscribe.next()`和`unsubscribe.complete()`来终止订阅。

接下来,在服务中创建一个私有的`dataSubject`对象,用于发送数据。通过调用`dataSubject.asObservable()`方法,将`dataSubject`对象转换为可观察对象`data$`。在`updateData`方法中,调用`getData`方法来获取最新的数据,并通过调用`dataSubject.next(data)`将数据发送给订阅者。在`getData`方法中,使用HTTP请求来获取数据,并通过`map`操作符从响应中提取出需要的数据。

通过以上方法,我们可以实现在Angular应用中实时刷新数据的功能。

代码如下:

import { Subject } from 'rxjs/Subject';
export class MyComponent implements OnInit, OnDestroy {
    private unsubscribe: Subject = new Subject();
    data: any;
    interval: any;
    ngOnInit() {
        this.refreshData();
        if(this.interval){
            clearInterval(this.interval);
        }
        this.interval = setInterval(() => {
            this.refreshData();
        }, 10000);
        this.myService.data$.takeUntil(this.unsubscribe)
            .subscribe(data => {
                this.data = data;
            });
    }
    ngOnDestroy() {
        this.unsubscribe.next();
        this.unsubscribe.complete();
    }
    refreshData(){
        this.myService.updateData()
            .takeUntil(this.unsubscribe)
            .subscribe();
    }
    doAction(){
        this.subscription.add(
            this.myService.doAction()
                .subscribe(result => {
                    if(result === true){
                        this.refreshData();
                    }
                })
        );
    }
}

import { Observable, BehaviorSubject } from 'rxjs';
export class MyService {
    private dataSubject: BehaviorSubject = new BehaviorSubject([]);
    data$: Observable = this.dataSubject.asObservable();
    updateData(): Observable  {
        return this.getData().do((data) => {
            this.dataSubject.next(data);
        });
    }
    // My data is an array of model objects
    getData(): Observable{
        return this.http.get('/path')
            .map((response: Response) => {
                let data = response.json() && response.json().your_data_objects;
                if(data){
                    return data;
                }
            })
    }
}

通过以上代码,我们可以在Angular应用中实现实时刷新数据的功能。

0
0 Comments

Angular2/4 : 实时刷新数据的原因和解决方法

在Angular中,实时刷新数据是一个常见的需求。在这篇文章中,我们将讨论为什么需要实时刷新数据以及如何实现。

问题的原因:

实时刷新数据是为了确保应用程序中的数据始终是最新的。在上述代码示例中,使用了一个定时器来每隔5秒钟刷新一次数据。这种方法可以正常工作,但是会导致内存泄漏的问题。每次刷新数据时,都会创建一个新的Observable对象,并且没有及时取消订阅。

解决方法:

为了避免内存泄漏,我们建议改变组件的实现方式。不要在每次http请求的响应中进行订阅,而是在组件的ngOnInit()方法中一次性订阅一个新的Observable属性data$。然后,使用定时器调用服务的updateData()方法来更新数据流,但不要进行订阅。当服务成功获取数据后,它会将下一个值推送到其Observable属性data$,从而在整个应用程序中提供了一个数据流。

代码示例:

在组件的ngOnInit()方法中:

this.myService.data$.subscribe(data => { // 一次性订阅数据流
    this.data = data;
})
this.refreshData();
this.interval = setInterval(() => { 
    this.refreshData(); 
}, 5000);

在服务中:

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

通过这种方法,我们避免了多次订阅的问题,并且可以在任何需要的组件中使用数据流。

最后,不要忘记在组件的ngOnDestroy()方法中清除定时器,使用clearInterval()方法。

在Angular应用程序中实现实时刷新数据是一个常见的需求。为了避免内存泄漏,我们建议改变组件的实现方式,一次性订阅数据流并使用定时器更新数据。通过这种方式,我们可以避免多次订阅的问题,并且可以在整个应用程序中使用数据流。

0