2016-09-04 6 views
0

반응 접근 방식을 사용하는 동안 모든 CRUD 작업을 수행하는 각도 2 공급자를 만들려고합니다. 그러나, 처음으로 loadAll()으로 전화를 걸면 내 목록에 내 이오니아 앱이 추가되지만, 그 후에는 언제든지 this.children.next(children)으로 전화를 걸면 목록이 업데이트되지 않습니다.각도 2 구성 요소가 리액턴스 제공자와 함께 * ngFor를 사용하여 업데이트되지 않음

또한 this.childrenService.createChild(child)으로 전화를 걸고 어떤 자식도 업데이트되지 않습니다.

내 환경 :

윈도우 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 (이온이없이) 내 업체에서이 두 가지를 변경하는 경우 : 내가 대신 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()이라는 제목뿐만 아니라 자식 목록은 각도로 업데이트되지만 내 이오니아 응용 프로그램에서는 업데이트되지 않습니다.

curChildren (createStream의 함수에서 찾을 수 있음)은 항상 비어 있습니다. curChildren은 현재 표시되는 것으로 가정합니다.

예상되는 모든 로그를 출력합니다. 요청을 올바르게받은 후 요청을 올바르게 처리합니다. 스트림을 통해 자식을 생성하지만 아무것도 업데이트하지 않는다고 말합니다.

나는 이것이 스트림을 통해 제대로 업데이트되지 않거나 제대로 rxjs를 사용하지 않을 수 있다고 생각합니다. 뭐가 될수 있었는지?

감사

답변

0

세 가지 주요 변화는이 문제를 해결하기 위해 필요했다 :

  • 제거 AddChildComponent - 직접 홈페이지에 아이를 추가
  • 변경 대신의 Observable
    ChildrenServicechildren 특성 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 구성 요소를 제거해야하는지 확신 할 수 없습니다.