Ответ 1
См. https://github.com/angular/angular/issues/19145
Я считаю, что это та же проблема. Наследование декоратора прерывается для миксинов, поэтому в настоящее время вам придется дублировать оформленные свойства.
Иногда я использую 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();
// ...
}
Ошибка:
Ошибка в ошибке: ошибки анализа шаблона: не удается привязать к тегу, поскольку он не является известным свойством "теста". ( "] [Тег] =" тег " > " )
См. https://github.com/angular/angular/issues/19145
Я считаю, что это та же проблема. Наследование декоратора прерывается для миксинов, поэтому в настоящее время вам придется дублировать оформленные свойства.
Основная проблема заключается в том, что компилятор angular имеет ограниченную функциональность. (читайте больше в docs)
Компилятор AOT использует метаданные, созданные MetadataCollector. Он использует объектную модель typescript (дерево Node
) (, почему AOT может использоваться только с typescript), чтобы собрать всю информацию, необходимую для создания ngfactory
(в некоторых случаях также ngsummary
).
Приведенные вами примеры совершенно различны для компилятора AOT:
1) Пользовательский декоратор
@Mixin([BehaviorInjected])
export class FooComponent {}
Angular MetadataCollector
будет включать декоратор @Mixin
в метаданных <<26 > (элемент в массиве decorators
) но будет пропущен, когда aot StaticReflector
вызовет simplify
, так как Mixin
декоратор не зарегистрирован на специальной карте, которая включает только строго (исходный код)
Более того, если мы даже включим его в эту карту, он все равно не будет выполнен во время компиляции aot, потому что он доступен только для поддерживаемых декораторов.
2) Вызов пользовательской функции
export class HomePageComponent extends TaggedComponent(MyComponent) {
MetadataCollector
добавит TaggedComponent
в коллекцию метаданных как символ типа {__symbolic: 'error', message: 'Symbol reference expected'};
, но также будет пропущен внутри StaticReflector
.
И насколько я знаю, в настоящее время нет решения для его поддержки.