angular组件便于扩展规范实例总结

  • 定义组件Inputs属性的interface规范
export interface ButtonInputsInterface {
  title: string;
}
  • 定义组件Outputs属性的interface规范
export interface ButtonOutputsInterface {
  clickStream: EventEmitter<MouseEvent>;
}
  • 默认值 可以通过angularprovider替换,可用于多模板等场景
@Injectable({
  providedIn: "root"
})
export class ButtonDefaultProps implements ButtonInputsInterface {
  title = "点我啊";
}
  • 组件接口 不实现任何逻辑
export abstract class ButtonAbstract {
  abstract onClick(e: MouseEvent): void;
  abstract bindEvent(e: string): void;
  abstract destroy(): void;
}
  • ButtonRef组件类抽离,只包含业务逻辑实现,不进行任何angular操作
// 没有template 类抽离
export class ButtonRef extends ButtonAbstract
  implements ButtonInputsInterface, ButtonOutputsInterface {
  // inputs
  title: string;
  // outputs
  clickStream: EventEmitter<MouseEvent>;
  private destroyed: Subject<any> = new Subject();
  constructor(
    private _default: ButtonDefaultProps,
    private ele: ElementRef,
    private parent: ButtonRef
  ) {
    super();
    // 默认值赋值
    Object.assign(this, this._default);
    console.log(parent);
  }
  onClick(e: MouseEvent) {
    this.clickStream.emit(e);
  }
  bindEvent(event: string) {
    return fromEvent(this.ele.nativeElement, event).pipe(
      tap((evt: MouseEvent) => {
        // 如果btn在一个btn里面,那么阻止事件上传
        if (this.hasParent()) {
          evt.stopPropagation();
        }
      }),
      takeUntil(this.destroyed)
    );
  }
  destroy() {
    this.destroyed.next();
    this.destroyed.complete();
  }
  hasParent() {
    return this.parent instanceof ButtonAbstract;
  }
}
  • angular组件,只包含组件生命周期及属性装饰,也就是只有angular特性相关内容
@Component({
  selector: "iwe7-button",
  template: `{{title}}<ng-content></ng-content>`
})
export class Iwe7ButtonComponent extends ButtonRef
  implements OnInit, OnDestroy {
  @Input() title: string;
  @Output() clickStream: EventEmitter<MouseEvent> = new EventEmitter();
  constructor(
    @Optional() _default: ButtonDefaultProps,
    ele: ElementRef,
    // 是否是btn下包含btn
    @Optional()
    @SkipSelf()
    parentBtn: Iwe7ButtonComponent
  ) {
    super(_default, ele, parentBtn);
  }

  ngOnInit() {
    this.bindEvent("click").subscribe((res: MouseEvent) => {
      this.onClick(res);
    });
  }

  ngOnDestroy() {
    this.destroy();
  }
}

猜你喜欢

转载自juejin.im/post/5b0ae72051882538903a9031
今日推荐