angular – 使用OnPush策略时,不会重新渲染子组件的视图

前端之家收集整理的这篇文章主要介绍了angular – 使用OnPush策略时,不会重新渲染子组件的视图前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@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);
    }
}

Child cmp从Parent 1获取userId,并且所需的用户包含在ngrx store(userList)中,但不会重新呈现child的视图.当Child的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 $成为一个Observable并保持相同的实例,而不是每次调用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));
}

猜你在找的Angularjs相关文章