【问题标题】:Inheritance of Angular 5 components with overriding the decorator propertiesAngular 5 组件的继承与覆盖装饰器属性
【发布时间】:2017-11-27 05:54:16
【问题描述】:

在 Angular 2/4 中,我们可以创建自定义装饰器来扩展父组件。装饰器属性的实际覆盖在自定义装饰器中根据需要进行处理。要获取我们使用的父注释:

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

更新到 Angular 5 后,这不再起作用。关于this 我们可以使用的答案:

target['__annotations__'][0] 用于获取父组件注解。

为了在 Angular 2/4 中的当前组件中设置注释,我们使用了:

let metadata = new Component(annotation); Reflect.defineMetadata('annotations', [ metadata ], target);

如何在 Angular 5 中设置当前组件注解?

【问题讨论】:

    标签: angular5


    【解决方案1】:

    最后我想出了一个自定义装饰器的实现(extendedcomponent.decorator.ts):

    import { Component } from '@angular/core';
    
    export function ExtendedComponent(extendedConfig: Component = {}) {
        return function (target: Function) {
            const ANNOTATIONS = '__annotations__';
            const PARAMETERS = '__paramaters__';
            const PROP_METADATA = '__prop__metadata__';
    
            const annotations = target[ANNOTATIONS] || [];
            const parameters = target[PARAMETERS] || [];
            const propMetadata = target[PROP_METADATA] || [];
    
            if (annotations.length > 0) {
                const parentAnnotations = Object.assign({}, annotations[0]);
    
                Object.keys(parentAnnotations).forEach(key => {
                    if (parentAnnotations.hasOwnProperty(key)) {
                        if (!extendedConfig.hasOwnProperty(key)) {
                            extendedConfig[key] = parentAnnotations[key];
                            annotations[0][key] = '';
                        } else {
                            if (extendedConfig[key] === parentAnnotations[key]){
                                 annotations[0][key] = '';
                            }
                        }
                    }
                });
            }
            return Component(extendedConfig)(target);
        };
    }
    

    使用示例:

    先照常实现父组件(myparent.component.ts):

    import { Component, Output, EventEmitter, Input } from '@angular/core';
    @Component({
        selector: 'my-component',
        templateUrl: 'my.component.html'
    })
    export class MyParentComponent implements OnInit {
        @Input() someInput: Array<any>;
        @Output() onChange: EventEmitter<any> = new EventEmitter();
    
        constructor(
            public formatting: FormattingService
        ) {
        }
    
        ngOnInit() {
    
        }
    
        onClick() {
            this.onChange.emit();
        }
    }
    

    之后实现继承父组件的子组件:

    import { Component, OnInit } from '@angular/core';
    import { ExtendedComponent } from './extendedcomponent.decorator';
    import { MyParentComponent } from './myparent.component';
    
    
    @ExtendedComponent ({
        templateUrl: 'mychild.component.html'
    })
    
    export class MyChildComponent extends MyParentComponent {
    }
    

    注意:这没有正式记录,在许多情况下可能不起作用。我希望它可以帮助其他人,但使用它需要您自担风险。

    【讨论】:

    • 它是否适用于 AOT?发布后你有什么改进吗?
    猜你喜欢
    • 1970-01-01
    • 2020-06-30
    • 2015-02-07
    • 2011-09-18
    • 2015-11-01
    • 2017-03-18
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多