angular2避免更新参考变量

时间:2017-01-04 07:10:25

标签: angular typescript observable rxjs5

为什么angular2正在更新变量的所有引用?

问题陈述: 我有一个服务,它在调用getData方法

时返回observable
@Injectable()
export class BuildingService {

constructor(private http: Http){       
  }

buildings$: Observable<Building[]>;

getData() : Observable<Building[]>{
     if (this.buildings$) {
        this.buildings$ = this.http.get('http://localhost:8080/buildings')
         .map(this.extractData)
         .publishReplay(1)
         .refCount();     
     }
     return this.buildings$;
  }

 private extractData(res: Response) {
    let body = res.json();
    return body;
} 
}
组件中的

我订阅了从getData方法返回的observable,并进行了一些过滤,并且工作正常

export class Component1 implements onInit{

   constructor(private _buildingService: BuildingService) {}

   buildings: Building[] = [];

   ngOnInit() {
        this._buildingService.getData()
        .subscribe(buildings => {
            this.buildings = buildings;
            this.buildings.forEach((building, index){
                if (building.id === 0) {
                    this.buildings.splice(index, 1);
                }
            });
        });     
   }

getUnfilteredData() {
    this._buildingService.getData()
        .subscribe(buildings => {
            this.buildings = buildings;         
        });
   }
}

但即使我也调用了getUnfilteredData(),我也会收到以前过滤的数据。有人可以解释为什么这种行为以及如何避免这种情况?

1 个答案:

答案 0 :(得分:2)

您正在使用.publishReplay(1).refCount();缓存正在运行的多个订阅者的数据。但是在您的ngOninit中,您将原始数据引用转移到this.buildings并拼接它。因此,您的缓存数据也会受到影响。

解决方案是在过滤之前将数组切片(复制)到this.buildings

 ngOnInit() {
        this._buildingService.getData()
        .subscribe(buildings => {
            this.buildings = buildings.slice();//slice instead of taking reference
            this.buildings.forEach((building, index){
                if (building.id === 0) {
                    this.buildings.splice(index, 1);
                }
            });
        });     
   }

或者你可以这样做:

 ngOnInit() {
            this.buildings = [];
            this._buildingService.getData()
            .subscribe(buildings => {

                buildings.forEach((building){
                    if (building.id !== 0) {
                        this.buildings.push(building);
                    }
                });
            });     
       }