如何找到装饰有某种装饰的所有房产?

时间:2018-02-28 14:13:35

标签: angular typescript typescript-decorator

我想将装饰器添加到已经使用Angular Input装饰器装饰的属性中 我需要这个,因为我想获得特定Input的一些(装饰的)Component属性。

我发现了非常相似的问题here,但有一个很大的区别(我需要它来处理属性而不是类,所以我不能在类上引入新变量作为已接受的答案)。

我想要实现的目标是:

export class BaseComponent 
{   
    @Input() id: number;
    @Input() @isFilter id2: number;
    @Input() @isFilter id3: number;

    public getDefaultFilter(): object
    {
        let o: Partial<this> = {};

        //Assign all properties on this(self), which has decorator isFilter, to o!!   

        return o;    //o should be {id2: whatever_is_set, id3: whatever_is_set}
    }
}

1 个答案:

答案 0 :(得分:6)

您可以使用reflect-metadata将修饰后的属性存储为元数据。例如。以下代码将存储用@isFilter()修饰的所有属性的名称。然后,您可以调用getFilteredProperties(this)来获取仅包含已修饰属性的this的浅表副本。

import 'reflect-metadata';

const metadataKey = Symbol('isFilter');

function isFilter(): (target: object, propertyKey: string) => void {
  return registerProperty;
}

function registerProperty(target: object, propertyKey: string): void {
  let properties: string[] = Reflect.getMetadata(metadataKey, target);

  if (properties) {
    properties.push(propertyKey);
  } else {
    properties = [propertyKey];
    Reflect.defineMetadata(metadataKey, properties, target);
  }
}

function getFilteredProperties(origin: object): object {
  const properties: string[] = Reflect.getMetadata(metadataKey, origin);
  const result = {};
  properties.forEach(key => result[key] = origin[key]);
  return result;
}

您可能还想查看TypeScript documentation for decorators

更新:由于此时Plunker似乎遇到了一些技术问题我借此机会为上面的代码设置Stackblitz。仍然可以找到旧的Plunker here