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

Что если массив зданий содержит еще один массив внутри? Похоже, что срез не работает с массивом внутри массива. –

+0

обновление ответа .. –

+0

вы можете просто фильтровать подписанные данные в свой массив компонентов. –

Смежные вопросы