2016-10-05 103 views
0

通過可觀察的對象集合循環,更新每個對象的最佳方法是什麼?如何遍歷並更新Firebase Observable中的所有對象?

我已經嘗試了以下方法,但是當我調用方法setActive()或者沒有任何反應,或者我發生了很多事情。

服務:

@Injectable() 
export class ProgramService { 
    private programs$: FirebaseListObservable<IProgram[]>; 

    constructor(private af: AngularFire, private auth: AuthService) { 
    private const path = `/programs/${auth.id}`; 
    this.programs$ = af.database.list(path); 
    } 

    getPrograms(): Observable<IProgram[]> { 
    return this.programs$; 
    } 

    setActive(currentProgram: IProgram) { 
    console.log('setActive: ' + currentProgram.$key); 
    this.programs$.map(programs => { 
     programs.map(program => { 
     let key = program['$key']; 
     if (key === currentProgram.$key) { 
      this.programs$.update(key, {"active": true}); 
     } else { 
      this.programs$.update(key, {"active": false}); 
     } 
     }) 
    }) 
    } 
} 

組件:

@Component({ 
    selector: 'programs', 
    templateUrl: 'app/program-list.component.html' 
}) 
export class ProgramListComponent implements OnInit { 
    errorMessage: string; 
    programs: IProgram[]; 

    constructor(
    private _ProgramService: ProgramService, 
    private _router: Router 
) {} 

    ngOnInit(): void { 
    this._ProgramService.getPrograms() 
     .subscribe(
     programs => this.programs = programs, 
     error => this.errorMessage = <any>error); 
    } 

    setActive(program: IProgram) { 
    this._ProgramService.setActive(program); 
    } 
} 

從我的分量I訂閱programs$觀察到的使用getPrograms()並列出所有節目在我的模板,並指出哪些程序是活動的。通過點擊另一行上的按鈕,我將其稱爲setActive()

模板:

<div class='panel panel-default'> 
    <table class='table table-hover' *ngIf='programs && programs.length'> 
    <tbody> 
     <tr *ngFor='let program of programs'> 
     <td (click)='gotoDetail(program)'> 
      <h4 class='list-group-item-heading'>{{ program.title }}</h4> 
      <p class='list-group-item-text'>{{ program.description }}</p> 
     </td> 
     <td class='text-right text-nowrap'> 
      <button type='button' class='btn btn-success' 
       *ngIf='program.active'>Current program</button> 
      <button type='button' class='btn btn-default' 
       *ngIf='!program.active' (click)='setActive(program)'>Set current</button> 
     </td> 
     </tr> 
    </tbody> 
    </table> 
</div> 

如果我運行上面什麼也沒有發生。它在我的方法中甚至沒有打到console.log()

如果我嘗試更改方法,比如我將this.programs$.map(programs => {更改爲this.programs$.forEach(programs => {,則我從Firebase獲取對象,並且更新邏輯運行良好。然後問題是我得到的數據太多,我得到了幾次對象,像這樣[obj1] .. [obj1],[obj2] .. [obj1],[obj2],[obj3] .. etc,從而更新每個對象幾次。下一次運行該方法時,結果會增加一倍,而且第三次運行時,它會得到非常多的數據,導致瀏覽器停止並放棄。

任何想法,輸入,提示,技巧,建議?

回答

0

我正在努力解決同樣的問題。事情是從firebase返回的觀察值以「金字塔」方式(例如{obj1},{obj1,obj2},{obj 1,obj 2,obj 3})進行。

一個簡單的方法來解決它將映射來自訂閱的響應。注意第一張「地圖」是rxjs地圖,第二張「地圖」是正規的es6地圖。

returnMappedPrograms() : Observable { return this.programs$.map(programs => {return programs.map((program) => {//do some thing to program..// return program}) }

雖然它解決了這個問題(至少我是這樣) - 這是真的過度(在每個第二張地圖運行對象幾次)。我認爲一個更好的解決辦法是重新創建觀察點,但我仍在研究這個問題