A veces uso Mixins para inyectar funciones repetidas como slugUrl() .
Pero no funciona con el compilador 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 { }Si compilo este código, el compilador lanza:
La propiedad 'ngClassControl' no existe en el tipo 'FooComponent'.
¿Algunas ideas?
Editar: como hubo alguien que preguntó, aquí hay otro ejemplo que usa mixins de TS que reproduce el problema, esta vez a nivel de plantilla.
Componentes:
@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) {}Mezclas:
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:
ERROR en Error: errores de análisis de plantilla: no se puede vincular a 'etiqueta' ya que no es una propiedad conocida de 'prueba'. ("][etiqueta]="etiqueta">")
El principal problema aquí es que el compilador angular tiene una funcionalidad limitada (lea más en los documentos )
El compilador AOT usa metadatos generados por MetadataCollector. Utiliza el modelo de objeto de mecanografiado (árbol de Node ) ( es por eso que AOT se puede usar solo con mecanografiado ) para recopilar toda la información necesaria para producir ngfactory (en algunos casos también ngsummary ).
Los ejemplos que proporcionó son completamente diferentes para el compilador AOT:
1) decorador personalizado
@Mixin([BehaviorInjected]) export class FooComponent {} Angular MetadataCollector incluirá el decorador @Mixin en los metadatos del símbolo FooComponent (elemento en la matriz de decorators ) pero se omitirá cuando aot StaticReflector llamará a simplify ya que el decorador Mixin no está registrado en un mapa especial que incluye solo decoradores estrictamente definidos ( código fuente )
Además, incluso si lo incluimos en ese mapa, no se ejecutará durante la compilación porque solo está disponible para los decoradores compatibles.
2) Llamar a la función personalizada
export class HomePageComponent extends TaggedComponent(MyComponent) { MetadataCollector agregará TaggedComponent a la colección de metadatos como un símbolo como {__symbolic: 'error', message: 'Symbol reference expected'}; pero también se omitirá dentro StaticReflector .
Y hasta donde yo sé, actualmente no hay una solución para respaldarlo.
Ver https://github.com/angular/angular/issues/19145
Creo que es el mismo problema. La herencia del decorador está rota para los mixins, por lo que actualmente tendrá que duplicar las propiedades decoradas.