Angular 4 AOT编译器不支持mixins

时间:2017-04-28 11:55:39

标签: angular angular-compiler-cli

有时我会使用Mixins来注入像slugUrl()这样的重复函数。

但它不适用于angular 4编译器。

export function Mixin(decorators: Function[]) {
  return function (classFn: Function) {
    decorators.forEach(decorator => {
      Object.getOwnPropertyNames(decorator.prototype).forEach(name => {
        classFn.prototype[name] = decorator.prototype[name];
      });
    });
  };
}


@Mixin([BehaviorInjected])
export class FooComponent {

}

如果我编译此代码,编译器会抛出:

  

属性'ngClassControl'在'FooComponent'类型上不存在。

有什么想法吗?

编辑:由于有人问过,这是使用TS mixins再现问题的另一个例子,这次是在模板级别。

组件:

@Component({
    selector: 'home-page',
    template: '<test [tag]="tag"></test>'
})
export class HomePageComponent extends TaggedComponent(MyComponent) {
    public tag = 'hi there';
}

@Component({
    selector: 'test',
    template: '<div></div>'
})
export class TestComponent extends TaggedComponent(MyComponent) {}

的混入:

type Constructor<T> = new(...args: any[]) => T;

export function TaggedComponent<T extends Constructor<{}>>(Base: T) {
     class TaggedBase extends Base {
        @Input() tag: string;
     };

     return TaggedBase;
}

export class MyComponent {
    protected subscriptions: Subscription = new Subscription();
  // ...
}

错误:

  

错误中的错误:模板解析错误:无法绑定到“tag”   不是“测试”的已知属性。 ( “] [标签] =” 标签 “&gt;” 中)

2 个答案:

答案 0 :(得分:5)

这里的主要问题是角度编译器的功能有限。(在the docs中阅读更多内容)

AOT编译器使用由MetadataCollector生成的元数据。它使用typescript对象模型(Node的树)(这就是为什么AOT只能与typescript 一起使用)来收集生成ngfactory所需的所有信息(在某些情况下)还有ngsummary)个文件。

您提供的示例与AOT编译器完全不同:

1)自定义装饰

@Mixin([BehaviorInjected])
export class FooComponent {}

Angular MetadataCollector将在@Mixin符号(FooComponent数组中的项目)的元数据中包含decorators装饰器,但在StaticReflectorsimplify将调用Mixin,因为export class HomePageComponent extends TaggedComponent(MyComponent) { 装饰器未在仅包含严格定义的装饰器的特殊地图中注册( will be skipped

此外,如果我们甚至将它包含在该地图中,它仍然不会在编译期间执行,因为它仅适用于受支持的装饰者。

2)调用自定义功能

MetadataCollector

TaggedComponent source code {__symbolic: 'error', message: 'Symbol reference expected'};将元数据集合作为StaticReflector之类的符号,但{{1}}内也will add

据我所知,目前还没有解决方案来支持它。

答案 1 :(得分:2)

请参阅https://github.com/angular/angular/issues/19145

我相信这是同样的问题。对于mixins,装饰器继承被破坏,所以目前你必须复制装饰属性。