16

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

}

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

“FooComponent”类型上不存在属性“ngClassControl”。

有任何想法吗?

编辑:因为有人问,这里是另一个使用 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();
  // ...
}

错误:

错误中的错误:模板解析错误:无法绑定到“标签”,因为它不是“测试”的已知属性。("][标签]="标签">")

4

2 回答 2

6

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

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

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

1) 自定义装饰器

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

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

此外,即使我们将它包含在该映射中,它仍然不会在 aot 编译期间执行,因为它仅适用于受支持的装饰器。

2) 调用自定义函数

export class HomePageComponent extends TaggedComponent(MyComponent) {

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

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

于 2017-10-18T12:57:16.693 回答
2

https://github.com/angular/angular/issues/19145

我相信这是同样的问题。装饰器继承对于 mixin 来说是破坏的,所以目前你将不得不复制装饰属性。

于 2017-10-17T17:02:10.647 回答