// 给予rxjs设计的组件模型import { Input, OnChanges, SimpleChanges, ChangeDetectorRef, OnInit, OnDestroy} from '@angular/core';import { Observable, merge } from 'rxjs';import { first, filter, takeWhile } from 'rxjs/operators';export class BaseComponent implements OnChanges, OnInit, OnDestroy { @Input() props: Observable= new Observable(); // 需要注销开关 needDestory: boolean = false; constructor() {} ngOnChanges(changes: SimpleChanges) { if ('props' in changes) { if (!changes['props'].isFirstChange) { this.__propsHandler(); } } } /** * 注销 */ ngOnDestroy() { this.needDestory = true; } ngOnInit() { this.__propsHandler(); } // 用户暴露给外部设置props的接口 setProps(props: Observable ) { this.props = merge(this.props, props); this.__propsHandler(); } private __propsHandler() { this.props = merge( // 添加默认值,解决默认值为null问题 this.props.pipe(first((val, idx) => idx === 0, {})), this.props ).pipe( // 去除{} filter(val => Object.keys(val).length > 0), // 自动注销 takeWhile(val => !this.needDestory) ); }}复制代码
建立一个测试组件
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, OnInit} from '@angular/core';import { BaseComponent } from '../base-component';@Component({ selector: 'base-test', templateUrl: './base-test.component.html', styleUrls: ['./base-test.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush})export class BaseTestComponent extends BaseComponent implements OnInit { constructor() { super(); }}复制代码
{
{props | async | json}}复制代码- 使用测试组件
复制代码
let i = 0;setInterval(() => { this.sub2.next({ a: i++, b: i++, c: i++ });}, 1000);复制代码
总结
这样完全绕过angular的changes,完全基于rxjs的核心去做,可能可以去掉ngZone