1

我目前正在将loopback3应用程序迁移到loopback4. 我已经使用loopback4带有一些元数据的自定义打字稿装饰器对模型中的属性进行了注释。

如何在启动时获取模型的完整列表并评估其元数据?

我做了一些实验LifeCycleObserver,但没有找到如何在所有模型都准备好时得到通知的方法,也没有找到它们的列表。

这是我要处理的元数据的简化示例。请注意:@propertyAcl是自定义装饰器。

export class Model1 extends AuditMixin(SoftdeleteMixin(AbstractEntity)) {

  // ...

  @property()
  @propertyAcl({
    'role1': Permission.READ_WRITE,
    'role2': Permission.READONLY,
  })
  myproperty?: string;

  // ...
}

我需要accesscontrol在启动时使用元数据配置外部库。这个想法是为每个模型创建基于属性的 acl。

4

1 回答 1

0

如何在启动时获取模型的完整列表并评估其元数据?

概述

使用@loopback/metadata创建Decorator和定义/获取元数据MetadataInspector

  1. 创建一个DecoratorFactory“A”
  2. 创建一个Context“B”
  3. 覆盖mergeWithInherited“A”中的函数,并在此函数中存储(定义)您在设计时注释到“B”的属性的元数据
  4. 通过“A”创建一个Decorator“C”
  5. 用“C”注释你想要的任何属性
  6. 在运行时获取“B”中的元数据

步骤 1 2 3 4

// 1
class A extends PropertyDecoratorFactory<object> {
    constructor(key: string, spec: object, options?: DecoratorOptions | undefined) {
        super(key, spec, options);
    }
    // 3
    mergeWithInherited(inheritedMetadata: MetadataMap<object>, target: Object, propertyName?: string, descriptorOrIndex?: TypedPropertyDescriptor<any> | number): any {
        // define metadata to "B"
        MetadataInspector.DesignTimeReflector.defineMetadata(`${target.constructor.name}.${propertyName}`, this.spec, B);
    }
}

// 2
export const B = new Context("B.context");

// 4
export function C(spec: object): PropertyDecorator {
    return A.createDecorator<object>(
        'C.decorator',
        spec,
    );
}


第 5 步

class ModelFoo extends Model {

    @property({
        type: 'string'
    })
    p1?: string;

    @C({ metadata: "this is ModelFoo" })
    @property({
        type: 'string'
    })
    p2?: string;

}

class ModelBar extends Model {

    @property({
        type: 'string'
    })
    p1?: string;

    @C({ metadata: "this is ModelBar" })
    @property({
        type: 'string'
    })
    p2?: string;

}

第 6 步

function Test() {
    // get all metadata keys in "B"
    let keys: string[] = MetadataInspector.DesignTimeReflector.getMetadataKeys(B);

    // output >>>> [ 'ModelFoo.p2', 'ModelBar.p2' ]
    console.log(keys);

    // get metadata with 'ModelFoo.p2' in "B"
    let metadata = MetadataInspector.DesignTimeReflector.getMetadata(keys[0], B);

    // output >>>> { metadata: 'this is ModelFoo' }
    console.log(metadata);

    // do somthing...
}

于 2019-09-11T15:40:50.437 回答