如何扩展/继承组件? [英] How to extend / inherit components?

查看:98
本文介绍了如何扩展/继承组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为已经部署在Angular 2中的某些组件创建扩展,而不必几乎完全重写它们,因为基本组件可能会发生更改,并希望这些更改也反映在其派生组件中.

I would like to create extensions for some components already deployed in Angular 2, without having to rewrite them almost completely, as the base component could undergo changes and wish these changes were also reflected in its derived components.

我创建了这个简单的示例,以试图更好地解释我的问题:

I created this simple example to try to explain better my questions:

具有以下基本组件app/base-panel.component.ts:

import {Component, Input} from 'angular2/core';

@Component({
    selector: 'base-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class BasePanelComponent { 

  @Input() content: string;

  color: string = "red";

  onClick(event){
    console.log("Click color: " + this.color);
  }
}

您是否想仅在例如示例颜色app/my-panel.component.ts的情况下创建另一种衍生成分,例如,改变基本成分的行为:

Would you like to create another derivative component only alter, for example, a basic component behavior in the case of the example color, app/my-panel.component.ts:

import {Component} from 'angular2/core';
import {BasePanelComponent} from './base-panel.component'

@Component({
    selector: 'my-panel',
    template: '<div class="panel" [style.background-color]="color" (click)="onClick($event)">{{content}}</div>',
    styles: [`
    .panel{
    padding: 50px;
  }
  `]
})
export class MyPanelComponent extends BasePanelComponent{

  constructor() {
    super();
    this.color = "blue";
  }
}

在Plunker中完整的工作示例

注意:显然,该示例很简单,可以解决,否则无需使用继承,但仅用于说明实际问题.

Note: Obviously this example is simple and could be solved otherwise no need to use inheritance, but it is intended only to illustrate the real problem.

正如您在派生组件app/my-panel.component.ts的实现中所看到的,重复了很多实现,并且真正继承的单个部分是class BasePanelComponent,但是@Component必须基本上完全重复,而不仅仅是更改的部分,如selector: 'my-panel'.

As you can see in the implementation of the derivative component app/my-panel.component.ts, much of the implementation was repeated, and the single part really inherited was the class BasePanelComponent, but the @Component had to basically be completely repeated, not just the changed portions, as the selector: 'my-panel'.

是否有某种方法可以完全继承Angular2组件,并继承标记/注释的class定义,例如@Component?

Is there some way to make a literally full inheritance of a component Angular2, inheriting the class definition of the markings/annotations, as for example @Component?

编辑1-功能请求

功能请求angular2已添加到GitHub上的项目中:扩展/继承angular2组件注释#7968

编辑2-已关闭的请求

由于该原因, 已被关闭不知道如何合并装饰器.别无选择.因此,我的看法是在问题中引用了.

The request was closed, for this reason, that briefly would not know how to merge the decorator will be made. Leaving us with no options. So my opinion is is quoted in the Issue.

推荐答案

替代解决方案:

Thierry Templier的答案是解决问题的另一种方法.

在与Thierry Templier进行了一些提问之后,我来到了下面的工作示例,该示例满足了我的期望,可以替代此问题中提到的继承限制:

After some questions with Thierry Templier, I came to the following working example that meets my expectations as an alternative to inheritance limitation mentioned in this question:

1-创建自定义装饰器:

1 - Create custom decorator:

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

2-具有@Component装饰器的基本组件:

2 - Base Component with @Component decorator:

@Component({
  // create seletor base for test override property
  selector: 'master',
  template: `
    <div>Test</div>
  `
})
export class AbstractComponent {

}

3-具有@CustomComponent装饰器的子组件:

3 - Sub component with @CustomComponent decorator:

@CustomComponent({
  // override property annotation
  //selector: 'sub',
  selector: (parentSelector) => { return parentSelector + 'sub'}
})
export class SubComponent extends AbstractComponent {
  constructor() {
  }
}

带有完整示例的插件.

这篇关于如何扩展/继承组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆