Angular2/4:覆盖另一个模块的组件

Dav*_*vid 7 inheritance typescript angular

我正在使用棱角4.3,打字稿2.2

我想基于相同的代码库创建多个应用程序(网站).所有网站都完全相同,但其中一些可能有一些额外的/不同的logc /模板.

我的想法是创建一个核心模块(主要包含组件),然后让应用程序使用该模块构建它,并根据需要重载: - 样式 - 模板(完全替换模板,或只修改模板的一部分)它)

  1. 如何覆盖核心模块中使用的组件?

我只设法覆盖路由中明确使用的组件,但我不能覆盖在Core模块的模板中直接调用的子组件.我是否需要动态注入这些组件?

  1. 继承组件时,是否可以仅覆盖父模板的一部分?

我想每个需要重写的模板部分都必须更改为核心模块中的一个组件(然后回到问题#1以使用子应用程序中的继承组件)

谢谢

Dav*_*vid 3

问题#1

这是一个对我有用的解决方案

步骤1

我将所有核心组件放在核心应用程序的核心模块中。

第2步

我在核心应用程序中声明了以下 CustomModule 功能

declare var Reflect : any;

export function CustomModule(annotations: any)
{
  return function (target: Function)
  {
    let parentTarget = Object.getPrototypeOf(target.prototype).constructor;
    let parentAnnotations = Reflect.getMetadata("annotations", parentTarget);

    let parentAnnotation = parentAnnotations[0];
    Object.keys(parentAnnotation).forEach(key =>
    {
      if (parentAnnotation[key] != null)
      {
        if (typeof annotations[key] === "function")
        {
          annotations[key] = annotations[key].call(this, parentAnnotation[key]);
        }
        else if (typeof Array.isArray(annotations[key]))
        {
          let mergedArrayItems = [];
          for (let item of parentAnnotation[key])
          {
            let childItem = annotations[key].find(i => i.name  == item.name);
            mergedArrayItems.push(childItem ? childItem : item);
          }

             annotations[key] = mergedArrayItems;
        }
        else if (annotations[key] == null)
        {  // force override in annotation base
          annotations[key] = parentAnnotation[key];
        }
      }
    });

    let metadata = new NgModule(annotations);

    Reflect.defineMetadata("annotations", [metadata], target);
  };
}
Run Code Online (Sandbox Code Playgroud)

步骤3

在另一个应用程序中,我创建了一个名为 InheritedModule 的不同模块,我创建了从 CoreModule 中的组件继承的组件。继承的组件必须与父组件具有相同的名称和相同的选择器。

步骤4

我让 InheritedModule 继承自 CoreModule。InheritedModule 是使用上面的 CustomModule 注解声明的(不要使用 NgModule)

该新模块应声明并导出在步骤 3 中创建的组件

@CustomModule({
  declarations: [    Component1, Component2  ], 
  exports: [  Component1, Component2],
  bootstrap: [AppComponent]
})
export class InheritedModule extends CoreModule
{
}
Run Code Online (Sandbox Code Playgroud)

步骤5

在子应用程序中导入 InheritedModule。

自定义模块函数将执行的操作是合并 2 个模块的注释,并在同名时将 CoreModule 的组件替换为 InheritedModule 的组件

问题2

我想每当我想覆盖核心应用程序中的部分 html 时,我就必须用微小的组件替换一些 html 模板。我暂时不接受答案,以防有人有更好的主意