为了账号安全,请及时绑定邮箱和手机立即绑定

用基类装饰器扩展组件装饰器

用基类装饰器扩展组件装饰器

Smart猫小萌 2019-10-21 09:25:50
我在每个组件上都有几个组件装饰器声明,例如:@Component({    moduleId: module.id,    directives: [BootstrapInputDirective]})如何将这些声明应用于所有组件?我试图用此装饰器创建一个基类,并用它扩展其他类,但是基类装饰似乎不适用于派生类。
查看完整描述

3 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

在Angular的最新版本之后,ComponentMetadata类不再可用,这是少数成员指出的。


这就是我实现CustomComponent使其工作的方式:


export function CustomComponent(annotation: any) {

  return function (target: Function) {

      let parentTarget = Object.getPrototypeOf(target.prototype).constructor;

      let parentAnnotations = Reflect.getOwnMetadata('annotations', parentTarget);


      let parentAnnotation = parentAnnotations[0];


      Object.keys(annotation).forEach(key => {

        parentAnnotation[key] = annotation[key];

      });

  };

}

希望能帮助到你!


编辑:前面的代码块,即使它起作用,它也会覆盖扩展类的原始元数据。在增强版的下面找到它,使您无需修改基类即可拥有多个继承和覆盖。


export function ExtendComponent(annotation: any) {

  return function (target: Function) {

    let currentTarget = target.prototype.constructor;

    let parentTarget = Object.getPrototypeOf(target.prototype).constructor;

    let parentAnnotations = Reflect.getOwnMetadata('annotations', parentTarget);


    Reflect.defineMetadata('annotations', [Object.create(parentAnnotations[0])], currentTarget);

    let currentAnnotations = Reflect.getOwnMetadata('annotations', currentTarget);


    Object.keys(annotation).forEach(key => {

        currentAnnotations[0][key] = annotation[key];

    });

};

}


查看完整回答
反对 回复 2019-10-21
?
慕村225694

TA贡献1880条经验 获得超4个赞

如果有人在寻找更新的解决方案,Thierry Templier的答案将是非常完美的。除了ComponentMetadata已被弃用。使用Component反而对我有用。


完整的Custom Decorator CustomDecorator.ts文件如下所示:


import 'zone.js';

import 'reflect-metadata';

import { Component } from '@angular/core';

import { isPresent } from "@angular/platform-browser/src/facade/lang";


export function CustomComponent(annotation: any) {

  return function (target: Function) {

    var parentTarget = Object.getPrototypeOf(target.prototype).constructor;

    var parentAnnotations = Reflect.getMetadata('annotations', parentTarget);


    var parentAnnotation = parentAnnotations[0];

    Object.keys(parentAnnotation).forEach(key => {

      if (isPresent(parentAnnotation[key])) {

        // verify is annotation typeof function

        if(typeof annotation[key] === 'function'){

          annotation[key] = annotation[key].call(this, parentAnnotation[key]);

        }else if(

          // force override in annotation base

          !isPresent(annotation[key])

        ){

          annotation[key] = parentAnnotation[key];

        }

      }

    });


    var metadata = new Component(annotation);


    Reflect.defineMetadata('annotations', [ metadata ], target);

  }

}

然后将其导入到您的新组件sub-component.component.ts文件中,并使用@CustomComponent而不是@Component这样:


import { CustomComponent } from './CustomDecorator';

import { AbstractComponent } from 'path/to/file';


...


@CustomComponent({

  selector: 'subcomponent'

})

export class SubComponent extends AbstractComponent {


  constructor() {

    super();

  }


  // Add new logic here!

}


查看完整回答
反对 回复 2019-10-21
  • 3 回答
  • 0 关注
  • 674 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信