2016-10-05 84 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}) }

虽然它解决了这个问题(至少我是这样) - 这是真的过度(在每个第二张地图运行对象几次)。我认为一个更好的解决办法是重新创建观察点,但我仍在研究这个问题