2017-01-04 85 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

您可以簡單地將訂閱的數據過濾到您的組件陣列中。 –