猿问

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

我在每个组件上都有几个组件装饰器声明,例如:


@Component({

    moduleId: module.id,

    directives: [BootstrapInputDirective]

})

如何将这些声明应用于所有组件?我试图用此装饰器创建一个基类,并用它扩展其他类,但是基类装饰似乎不适用于派生类。


Smart猫小萌
浏览 717回答 3
3回答

胡子哥哥

在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];    });};}

慕村225694

如果有人在寻找更新的解决方案,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!}
随时随地看视频慕课网APP

相关分类

AngularJS
我要回答