Angular 4 AOT编译器不支持mixins

Ser*_*nho 16 angular-compiler-cli angular

有时我使用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 {

}
Run Code Online (Sandbox Code Playgroud)

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

属性'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) {}
Run Code Online (Sandbox Code Playgroud)

混入:

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();
  // ...
}
Run Code Online (Sandbox Code Playgroud)

错误:

错误中的错误:模板解析错误:无法绑定到'tag',因为它不是'test'的已知属性.( "] [标签] =" 标记 ">")

yur*_*zui 6

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

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

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

1)定制装饰

@Mixin([BehaviorInjected])
export class FooComponent {}
Run Code Online (Sandbox Code Playgroud)

Angular MetadataCollector@MixinFooComponent符号的元数据中包含装饰器(decorators数组中的项目),但是在aot 调用时将被跳过,因为装饰器未在仅包含严格定义的装饰器的特殊映射中注册(源代码StaticReflectorsimplifyMixin

而且,即使我们甚至将其包含在该映射中,它也不会在aot编译期间执行,因为它仅适用于受支持的装饰器。

2)调用自定义功能

export class HomePageComponent extends TaggedComponent(MyComponent) {
Run Code Online (Sandbox Code Playgroud)

MetadataCollector TaggedComponent像符号一样添加到元数据集合中,{__symbolic: 'error', message: 'Symbol reference expected'};但是也会在内部被跳过StaticReflector

据我所知,目前尚无解决方案来支持它。

  • @David AFAIK angular 5 aot 编译器没有修复它 (2认同)