覆盖/扩展第三方组件的模板

Joe*_*ida 11 typescript angular

我目前正在导入第三方组件.对于我的用例,我需要覆盖该特定的组件模板.

由于这是第三方组件,并通过npm包导入,因此我不想更改组件,因此每次更新软件包时都不必更新它.

有没有办法覆盖另一个组件的模板?

我知道你可以使用,<ng-content>如果你想注入一些元素.但这里不可行.

html是这样的:

<third-party-component [items]="items" [example]="example">
Run Code Online (Sandbox Code Playgroud)

控制器是这样的:

import {THIRD_PARTY_DIRECTIVES} from 'ng2-select/ng2-select';

@Component({
  selector: 'example-component',
  directives: [THIRD_PARTY_DIRECTIVES]
})
export class Example {

  private items: Array<string> = [
    'whatever', 'whatever2', 'whatever3'
  ];
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在<third-party-component>不编辑特定组件声明的情况下指定我想要的模板?或者甚至只扩展它?

Joe*_*ida 14

玩完之后.一个简单的扩展将适用于我的用例.

基本上我创建了一个扩展的类thirdPartyClass.

这里发生的是我thirdPartyClass通过创建自己的选择器并仅导入类来覆盖模板.

像这样的东西:

import {component} from 'angular2/core';
import {thirdPartyClass} from 'example/example';

@Component({
  selector: 'my-selector',
  template: '<div>my template</div>'
})

export class MyOwnComponent extends thirdPartyClass {
  constructor() {
     super()
  }
}
Run Code Online (Sandbox Code Playgroud)

备注:

  • 如果您使用此方法,请不要忘记导入thirdPartyClass模板中使用的任何管道.
  • 如果功能更新thirdPartyClass取决于模板,则需要手动更新.
  • 我更喜欢这个解决方案来引用ReflectMetaData,因为它是一个简单的扩展而不是访问注释并强制更改它.


Sas*_*sxa 3

您可以使用 Reflect 来更改组件的元数据。这是一个超级简单的例子

import {Component} from 'angular2/core'

@Component({
  selector: 'thing',
  template: `Hi!`,
})
export class Thing {}

annotations = Reflect.getMetadata('annotations', Thing);
for (let i = 0; i < annotations.length; i += 1) {
  if (annotations[i].constructor.name === 'ComponentMetadata') {
    annotations[i].template = 'Ho!';
    break;
  }
}

@Component({
  selector: 'my-app',
  directives: [Thing],
  template: `<thing></thing>`,
})
export class App {}
Run Code Online (Sandbox Code Playgroud)

只需确保在将模板注入父组件之前更新模板即可。另请检查您需要访问哪些元数据DirectiveMetadata(可能适合您的情况)。