2016-09-04 23 views
0

リアクティブ・アプローチを使用している間にすべてのCRUD操作を実行する角度2プロバイダを作成しようとしています。しかし、最初にloadAll()と呼ぶと私のIonic Appが私のリストに追加されますが、それ以降は​​と呼ぶと、リストは更新されません。角度2コンポーネントがリアクティブ・プロバイダで* ngForを使用して更新されない

また、私はthis.childrenService.createChild(child)と呼んでおり、子供も更新されていません。

私の環境:

のWindows 10上で実行している、とイオン--version実行するには、私に私package.jsonの2.0.0-beta.35

パートを与えます:

... 
"@angular/common": "2.0.0-rc.4", 
"@angular/compiler": "2.0.0-rc.4", 
"@angular/core": "2.0.0-rc.4", 
"@angular/forms": "0.2.0", 
"@angular/http": "2.0.0-rc.4", 
"@angular/platform-browser": "2.0.0-rc.4", 
"@angular/platform-browser-dynamic": "2.0.0-rc.4", 
"ionic-angular": "2.0.0-beta.11", 
"ionic-native": "1.3.10", 
"ionicons": "3.0.0" 
... 

プロバイダクラス:

import {Injectable, EventEmitter} from '@angular/core'; 
import { Http } from '@angular/http'; 
import {Child} from "../../models/child.model"; 
import {Constants} from "../../models/Constants"; 
import 'rxjs/Rx'; 
import {Observable, Subject, ReplaySubject} from "rxjs"; 
import {IChildOperation} from "../../models/IChildOperation"; 

@Injectable() 
export class ChildrenService { 

    public children: Subject<Child[]> = new Subject<Child[]>(); 
    private updates: Subject<IChildOperation> = new Subject<IChildOperation>(); 
    private createStream: Subject<Child> = new Subject<Child>(); 

    constructor(private http: Http) { 
    this.updates 
    .scan((children : Child[], operation: IChildOperation) => { 
     return operation(children); 
     }, []) 
    .subscribe(this.children); 

    this.createStream 
    .map((newChild: Child) => { 
     //"Do what is in this returned method for each child given to this create object (via this.createStream.next(newChild))" 
     return (curChildren: Child[]) => { 
     console.log("Creating a new child via stream."); 
     return curChildren.concat(newChild); 
     } 
    }) 
    .subscribe(this.updates); 

    this.loadAll(); 
    } 

    createChild(newChild: Child) { 
    console.log("Creating child..."); 
    this.http.post(`${Constants.CHILDREN_API}`, newChild) 
    .map(res=>res.json()) 
    .subscribe((newChild: Child) => { 
     console.log("Child Created!"); 
     console.log(newChild); 
     this.createStream.next(newChild); 
    }); 
    } 

    loadAll() { 
    this.http.get(`${Constants.CHILDREN_API}`) 
    .map(res => res.json()) 
    .subscribe(
     (children: Child[]) => { // on success 
     console.log(children); 
     this.children.next(children); 
     }, 
     (err: any) => { // on error 
     console.log(err); 
     }, 
    () => { // on completion 
     } 
    ); 
    } 
} 

ホームコンポーネント

import {Component, OnInit, ChangeDetectionStrategy} from '@angular/core'; 
import {NavController, ModalController} from 'ionic-angular'; 
import {AddChildPage} from "../add-child/add-child"; 
import {ChildrenService} from "../../providers/children/ChildrenService"; 
import {Child} from "../../models/child.model"; 
import {AsyncPipe} from "@angular/common"; 

@Component({ 
    templateUrl: 'build/pages/home/home.html', 
    providers: [ ChildrenService ], 
    pipes: [AsyncPipe], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class HomePage implements OnInit { 
    constructor(
    private nav: NavController, 
    private childrenService: ChildrenService, 
    private modalCtrl: ModalController) {} 
    } 

    goToAddChild() { 
    this.nav.push(AddChildPage); 
    } 
} 

ホームテンプレート

... 
    <ion-list> 
    <ion-item *ngFor="let child of childrenService.children | async"> 
     {{ child.name }} 
    </ion-item> 
    </ion-list> 

    <button secondary fab fab-fixed fab-bottom fab-right margin 
      (click)="goToAddChild()"><ion-icon name="person-add"></ion-icon></button> 
... 

AddChildはコンポーネント

UPDATE 210

は、私は私の反応プロバイダをテストしただけ角度2(イオン2なし)と私は私のプロバイダでは、これら二つのことを変更した場合:私はするのではなく、ReplaySubjectに子を変更し

export class ChildrenService { 

    //Changed child from Subject to ReplaySubject 
    public children: ReplaySubject<Child[]> = new ReplaySubject<Child[]>(); 
    ... 


    createChild(newChild: Child) { 
    console.log("Creating child..."); 
    this.http.post(`${Constants.CHILDREN_API}`, newChild) 
    .map(res=>res.json()) 
    .subscribe((newChild: Child) => { 
     console.log("Child Created!"); 
     console.log(newChild); 
     this.createStream.next(newChild); 
     this.loadAll(); //This is the NEW line in createChild 
    }); 
    } 

サブジェクトは、新しい子のために呼び出される関数内にthis.loadAll()と呼ばれているだけでなく、子どものリストはAngularで更新されますが、私のIonicアプリでは更新されません。

私は、curChildren(createStreamの関数にあります)が常に空であることに気付きました。 curChildrenは現在表示されているものと仮定しました。

これは、子供の作成、それがポスト要求を正しく行うことを伝えるすべての予想されるログを出力します。要求を受け取った後、ストリームを介して子を作成しても何も更新されません。

ストリームを正しく更新しない、またはrxjsを正しく使用していない可能性があります。どうなり得るか?

答えて

0

3つの主要な変更は、この問題を解決するために必要であった

ありがとう:

  • はAddChildComponentを削除 - Observable
    の代わりにChildrenService
  • ホームページで直接変更を子を追加childrenプロパティSubject/ReplaySubject
  • this.updates.scan(...).subscribe(this.children)の代わりにthis.children = this.updates.scan(...)に変更してください

ChildrenService.ts

... 
export class ChildrenService { 

    public children: Observable<Child[]> = new Observable<Child[]>(); 
    ... 

    constructor(private http: Http) { 
    //AsyncPipe will take care of subscribing, so just set it to this.updates 
    this.children = this.updates 
    .scan((children : Child[], operation: IChildOperation) => { 
     return operation(children); 
     }, []); 

    ... 
    } 
} 

奪う: AsyncPipeは、この問題のために素晴らしい作品。しかし、すべての作成ロジックがChildrenServiceに含まれているため、なぜAddChildコンポーネントを削除しなければならなかったのかまだ分かりません。

関連する問題