2017-01-04 88 views
0

为什么angular2更新变量的所有引用?angular2避免更新参考变量

问题陈述: 我有上调用getData方法

@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方法返回,并做一些过滤返回观察到的一个服务,它是工作的罚款

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()也,我以前过滤的数据。有人可以解释为什么这种行为以及如何避免这种情况?

+0

你第一次调用'ngOnInit',然后过滤'this.buildings'。稍后你调用相同的服务,并在回调'建筑物'是'this.buildings'?你可以'console.log(建筑物);'订阅内? – echonax

+0

@echonax我做了console.log(建筑物)里面的getUnfilteredData。我正在过滤数据而不是未过滤的数据。 –

回答

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); 
        } 
       }); 
      });  
     } 
+0

如果建筑物数组里面包含一个更多的数组,那该怎么办?看起来像slice不能处理数组中的数组。 –

+0

更新答案.. –

+0

您可以简单地将订阅的数据过滤到您的组件阵列中。 –