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

时间:2016-01-26 16:19:16

标签: typescript angular

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

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

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

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

html是这样的:

<third-party-component [items]="items" [example]="example">

控制器是这样的:

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'
  ];
}

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

2 个答案:

答案 0 :(得分:14)

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

基本上我创建了一个扩展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() } } 的模板。

这样的事情:

thirdPartyClass

备注

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

答案 1 :(得分:3)

您可以使用Reflect更改组件的元数据。这是super simple example

<?xml version="1.0" encoding="utf-8"?>
        <android.support.design.widget.CoordinatorLayout>
           <appbar ... />
                 <toolbar .... />

     <TextView  android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Hello World"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

        </android.support.design.widget.CoordinatorLayout>

只需确保在之前更新模板将其注入父组件。另外,请检查您需要访问的which metadata,在您的情况下可能是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 {}