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

私のコンポーネントから私はgetPrograms()を使用して、観察programs$を購読し、私のテンプレートですべてのプログラムを一覧表示し、アクティブなプログラムを示しています。アクティブなもの以外の行のボタンをクリックすると、私は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のようにすべてのオブジェクトを何度も取得し、それによって各オブジェクトを何度か更新します。次回はメソッドを実行すると結果が倍になり、3回目に実行すると、ブラウザが停止して放棄するデータが非常に多くなります。

アイデア、入力、ヒント、トリック、提案はありますか?

答えて

0

私は同じ問題で苦労しています。事実は、ファイアベースからの復帰が「ピラミッド」(例えば、{obj1}、{obj1、obj2}、{obj1、obj2、obj3})になるという観察可能なことである。

これを解決するには、サブスクリプションからの応答をマップするのが一番です。最初の "マップ"はrxjsマップであり、2番目の "マップ"は通常のes6マップであることに注意してください。

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

それは(少なくとも私の場合)の問題を解決するのに - それは、(第2マップは、各上で実行される複数回オブジェクト)本当に過大です。私はより良い解決策は、観測可能なものを再作成することだと思うが、私はまだその問題について研究している

関連する問題