Angular 4 AOT编译器不支持mixins
Angular 4 AOT compiler does not support mixins
有时我使用 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 {
}
如果我编译这段代码,编译器会抛出:
Property 'ngClassControl' does not exist on type 'FooComponent'.
有什么想法吗?
编辑:既然有人问过,这里是另一个使用 TS 混入重现问题的例子,这次是在模板级别。
组件:
@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();
// ...
}
错误:
ERROR in Error: Template parse errors: Can't bind to 'tag' since it
isn't a known property of 'test'. ("][tag]="tag">")
见https://github.com/angular/angular/issues/19145
我相信这是同样的问题。混合器的装饰器继承被破坏,因此目前您将不得不复制装饰属性。
这里的主要问题是 angular 编译器的功能有限。(在 the docs 中阅读更多内容)
AOT 编译器使用由 MetadataCollector 生成的元数据。它使用 typescript 对象模型(Node
的树)(这就是 AOT 只能与 typescript 一起使用的原因)来收集生成 ngfactory
所需的所有信息(在某些情况下还有 ngsummary
) 文件。
您提供的示例与 AOT 编译器完全不同:
1) 自定义装饰器
@Mixin([BehaviorInjected])
export class FooComponent {}
Angular MetadataCollector
will include @Mixin
decorator in metadata of FooComponent
symbol(item in decorators
array) but it will be skipped when aot StaticReflector
will call simplify
since Mixin
decorator is not registered in special map that includes only strictly defined decorators (source code)
此外,即使我们甚至将它包含在该映射中,它仍然不会在 aot 编译期间执行,因为它仅适用于支持的装饰器。
2) 调用自定义函数
export class HomePageComponent extends TaggedComponent(MyComponent) {
MetadataCollector
will add TaggedComponent
to metadata collection as symbol like {__symbolic: 'error', message: 'Symbol reference expected'};
but it also will be skipped 里面 StaticReflector
.
据我所知,目前还没有支持它的解决方案。
有时我使用 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 {
}
如果我编译这段代码,编译器会抛出:
Property 'ngClassControl' does not exist on type 'FooComponent'.
有什么想法吗?
编辑:既然有人问过,这里是另一个使用 TS 混入重现问题的例子,这次是在模板级别。
组件:
@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();
// ...
}
错误:
ERROR in Error: Template parse errors: Can't bind to 'tag' since it isn't a known property of 'test'. ("][tag]="tag">")
见https://github.com/angular/angular/issues/19145
我相信这是同样的问题。混合器的装饰器继承被破坏,因此目前您将不得不复制装饰属性。
这里的主要问题是 angular 编译器的功能有限。(在 the docs 中阅读更多内容)
AOT 编译器使用由 MetadataCollector 生成的元数据。它使用 typescript 对象模型(Node
的树)(这就是 AOT 只能与 typescript 一起使用的原因)来收集生成 ngfactory
所需的所有信息(在某些情况下还有 ngsummary
) 文件。
您提供的示例与 AOT 编译器完全不同:
1) 自定义装饰器
@Mixin([BehaviorInjected])
export class FooComponent {}
Angular MetadataCollector
will include @Mixin
decorator in metadata of FooComponent
symbol(item in decorators
array) but it will be skipped when aot StaticReflector
will call simplify
since Mixin
decorator is not registered in special map that includes only strictly defined decorators (source code)
此外,即使我们甚至将它包含在该映射中,它仍然不会在 aot 编译期间执行,因为它仅适用于支持的装饰器。
2) 调用自定义函数
export class HomePageComponent extends TaggedComponent(MyComponent) {
MetadataCollector
will add TaggedComponent
to metadata collection as symbol like {__symbolic: 'error', message: 'Symbol reference expected'};
but it also will be skipped 里面 StaticReflector
.
据我所知,目前还没有支持它的解决方案。