如何扩展/继承组件?

2023-12-23

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

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

具有以下基本组件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:

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 中的完整工作示例 http://plnkr.co/edit/bWa1JmH7NaSaJffLsl0x?p=preview

注意:显然这个例子很简单,可以解决,否则不需要使用继承,但它只是为了说明真正的问题。

正如您在衍生组件的实现中所看到的app/my-panel.component.ts,大部分实现都是重复的,真正继承的部分是class BasePanelComponent,但是@Component基本上必须完全重复,而不仅仅是改变的部分,因为selector: 'my-panel'.

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

编辑 1 - 功能请求

将功能请求 angular2 添加到 GitHub 上的项目中:扩展/继承 angular2 组件注释 #7968 https://github.com/angular/angular/issues/7968

编辑 2 - 已关闭的请求

请求已关闭,为此原因 https://github.com/angular/angular/issues/7968#issuecomment-219865739,短暂地不知道如何合并装饰器。让我们别无选择。所以我的意见是本期引用 https://github.com/angular/angular/issues/7968#issuecomment-222496110.


替代解决方案:

Thierry Templier 的这个回答是解决该问题的另一种方法。 https://stackoverflow.com/a/36837482/2290538

在向 Thierry Templier 提出一些问题后,我得到了以下工作示例,它满足我的期望,作为此问题中提到的继承限制的替代方案:

1 - 创建自定义装饰器:

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 装饰器的基础组件:

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

}

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

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

带有完整示例的 Plunkr。 https://plnkr.co/edit/TPps03QCGQCWbX6oVKXp?p=preview

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何扩展/继承组件? 的相关文章

随机推荐

  • 使用 SQLite 获取本周的数据

    我试图在 sqlite 中获取本周的数据 但似乎我错过了一些东西 因为我得到了错误的信息 更具体地说 我想检索数据库中具有时间戳的所有数据 其日期属于本周 本周可能从周日或周一开始 即 26 2 12 03 03 12 目前我正在使用这样的
  • 即使有垂直滚动,如何将绝对定位的项目保留在网站底部?

    我有一个具有绝对位置的页脚 footer position absolute bottom 0 height 43px padding 0 background color 333333 width 100 color 737373 tex
  • Django 密码问题

    我正在为用户使用模型 如下所示 class UserForm forms ModelForm class Meta model User fields username password email 但密码字段显示为常规文本字段 而不是密码
  • 如何使用 OpenXml 2.0 将任何文件类型嵌入到 Microsoft Word 中

    我花了很多时间试图找到一种使用 OpenXml 2 0 将任何文件嵌入 Microsoft Word 的好方法 Office 文档相当简单 但其他文件类型 例如 PDF TXT GIF JPG HTML 等 又如何呢 在 C 中 让它适用于
  • 如何使用 Bouncy Castle 将私钥附加到证书

    我有两个 PEM 文件需要在 Bouncy Castle 中加载 一个文件是证书 另一个文件是私钥 使用本文答案中的代码 如何读取 Pem 证书和私钥文件并创建 Bouncy Castle X509Certificate 和 Bouncy
  • Python 中的重试函数 [重复]

    这个问题在这里已经有答案了 前段时间 我需要一个retryR 中的函数处理缓慢的服务器响应 该函数将具有以下行为 尝试一个操作 函数或方法 如果失败 请稍等一下 然后重试 x10 我想出了以下几点 retry lt function fun
  • Ant + 类路径问题

    我已经编写了一个 ANT 脚本 最后正在构建 jar 这是 jar 部分的建筑
  • 使用内联脚本时在 Python 中将 unicode 字符打印到控制台的正确方法

    我正在寻找一种使用 Python 2 x 将 unicode 字符打印到支持 UTF 8 的 Linux 控制台的方法print method 我得到的是 python2 7 c print u 我想要的是 python2 7 c prin
  • Ipython 笔记本 - 无法打开

    我尝试打开 ipython 笔记本但没有成功 不知道为什么 当我输入命令 ipython notebook 时 我收到的输出是 bash usr local bin ipython usr local opt python bin pyth
  • 图片框位图缩放

    我有一个Picturebox和一大堆Bitmaps可以在其中显示 位图与其他位图相比的相对大小对用户来说很重要 他们需要能够看出一张图像比另一张图像小或大 位图还必须完全适合图片框 并且图片框不能调整大小 当简单地在一个巨大的图片框中显示未
  • 将 d3.js SVG 代码转换为独立程序 - 有什么建议吗?

    我有一些用 d3 js 编写的脚本 可以生成 SVG 图表 我想使用独立程序生成这些图表 将这些脚本转换为在批处理模式下运行而不需要浏览器的最简单方法是什么 你可以 将其转换为node js http nodejs org程序 您可以访问文
  • 在 Excel-VBA 中使用 RegEx 替换文本

    我在 Excel 中有如下数据 此处一行 Excel 中的一个单元格 07 July 2015 12 02 14 July 2015 17 02 12 August 2015 22 02 01 September 2015 11 02 我想
  • jQuery 移动选项卡和锚点

    我想使用 jQuery Mobile 创建一个选项卡式移动页面 我已经掌握了创建选项卡 例如 Tab1 Tab2 Tab3 Tab4 以及让每个选项卡加载新内容页面的基础知识 我将如何在特定选项卡中使用锚点 例如 如果有人想要为一个链接添加
  • 如何使用 NodeJS 验证 Hmac?

    我可以使用以下代码通过 NodeJS 成功创建 Hmac 稍微改变示例 https nodejs org api crypto html cryptocreatehmacalgorithm key options https nodejs
  • 如何通过 ssh 连接到 docker 容器

    我正在运行容器hypriot rpi busybox httpd 我正在尝试 ssh 到 docker 容器 但出现以下错误 pi raspberrypi docker exec it cc55da85b915 bash rpc error
  • 将键码的字符串表示形式转换为 Qt::Key (或任何 int)并返回

    我想将代表键盘上的键的字符串转换为键码枚举 例如Qt Key http doc qt digia com 4 7 qt html Key enum 或其他任何东西 转换示例如下 Ctrl to Qt Key Control Up to Qt
  • 远程处理 - 有关客户端的信息。 C#

    在 net 2 0 上使用远程处理时是否可以找到 获取有关连接客户端的一些信息 我想知道有关服务器端连接客户端的一些信息 以便我可以采取相应的行动 这是一个小型且非常本地化的应用程序 同时连接 请求的客户端数量最多不会超过 10 个 在每个
  • Facebook 登录 JS - FB.Event.subscribe('auth.login') 无需点击登录按钮即可触发

    我真的需要您帮助我尝试在我的网站上实现 使用 Facebook 登录 功能 基本上 我正在努力实现以下目标 如果用户之前已确认该应用程序并单击 FB 登录按钮 在我的网站上 他们登录到该网站 使用网站的用户 与 Facebook 用户 ID
  • Jquery 如果它是第一次单击元素

    我需要我的脚本在第一次单击元素时执行某些操作 并在单击 2 3 4 等时继续执行不同的操作 selector click function I would realy like this variable to be updated var
  • 如何扩展/继承组件?

    我想为 Angular 2 中已经部署的一些组件创建扩展 而不必几乎完全重写它们 因为基础组件可能会发生更改 并希望这些更改也反映在其派生组件中 我创建了这个简单的示例来尝试更好地解释我的问题 具有以下基本组件app base panel