2017-08-06 4 views
2
@Component({ 
    selector: "parent", 
    template: `<child [userId]="(userId$ | async)"></child>`, 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class ParentCmp implements OnInit { 
    userId$: BehaviorSubject<string> = new BehaviorSubject<string>(null); 

    constructor(private activatedRoute: ActivatedRoute) { } 
    ngOnInit() { 
     this.activatedRoute.queryParams.subscribe(query => { 
      //notify child with BehaviorSubject 
      this.userId$.next(query["userid"]) 
     } 
    } 
} 

@Component({ 
    selector: "child", 
    template: `<div *ngIf="(userState$ | async) && userId"> 
        {{(userState$ | async).user.id)}} 
       </div>`, 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class ChildCmp implements OnChanges { 
    @Input() userId: string; 
    private userState$: Observable<User>; 

    constructor(private store: Store<store.AppState>) { } 
    ngOnChanges(changes: SimpleChanges) { 
     //when it gets userId it starts to track fit user in ngrx store 
     this.userState$ = this.store 
       .select(state => state.user-list)     
       .map(userList => userList[this.userId]) 
       .filter(user => !!user); 
    } 
} 

子のcmpは親からuserIdを取得し、必要なユーザーはngrx store(userList)に含まれますが、子ビューは再レンダリングされません。これは、ChildのChangeDetectionStrategyがデフォルトの場合に完全に機能します。ここで何が間違っていますか? 角度V2.4OnPush戦略を使用すると、子コンポーネントのビューが再レンダリングされません。

+1

プランナーを作成できますか? – yurzui

答えて

0

あなたはngOnChanges()にモデルを変更する場合は、明示的に

export class ChildCmp implements OnChanges { 
    @Input() userId: string; 
    private userState$: Observable<User>; 

    constructor(
     private store: Store<store.AppState>, 
     private cdRef:ChangeDetectorRef 
    ) { } 
    ngOnChanges(changes: SimpleChanges) { 
     //when it gets userId it starts to track fit user in ngrx store 
     this.userState$ = this.store 
       .select(state => state.user-list)     
       .map(userList => userList[this.userId]) 
       .filter(user => !!user); 
     this.cdRef.detectChanges(); 
    } 
} 

またはおそらくより良いたびにuserStates$観察可能にし、代わりに新しいものを作成するのと同じインスタンスを保持する変化検出を起動する必要がありますngOnChangesと呼びます:

userId$: Subject<User> = new Subject<User>(); 

ngOnChanges(changes: SimpleChanges) { 
    //when it gets userId it starts to track fit user in ngrx store 
    this.store 
      .select(state => state.user-list)     
      .map(userList => userList[this.userId]) 
      .filter(user => !!user) 
      .subscribe((user) => this.userId.next(user)); 
} 
+0

*小さな質問*は 'state.user-list'は正しいステートメントですか?私は 'state ['user-list'] 'ではないはずです。 –

+0

@PankajParkar @Mergasovの質問がありますか? –

+0

@GünterZöchbauerは主題について考えてくれてありがとう:主題が新しい価値を生み出すとき、コンポーネントの表示は再レンダリングされます。 – Mergasov

関連する問題