@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从父节点获取用户id,所需的用户包含在ngrx存储(userlist)中,但子节点的视图不会重新呈现。当孩子的ChangeDetectionStrategy为默认值时,它工作得很好。这里有什么问题吗?
角度V2.4

最佳答案

如果在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$可观察并保持同一个实例,而不是每次创建一个新的实例,称为“cc>”:
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));
}

07-24 20:27