Carregar dinamicamente os componentes existentes Versão final do Angular 2
Estou tentando carregar dinamicamente um componente na versão final 2.0.0.
Usando o RC5, eu estava carregando usando o seguinte código:
Crie uma diretiva para carregar os controles:
import {
CheckboxComponent, CheckboxListComponent,DatePickerComponent
} from '../components/';
@Directive({
selector: '[ctrl-factory]'
})
export class ControlFactoryDirective implements OnChanges {
@Input() model: any;
constructor(private vcRef: ViewContainerRef, private resolver: ComponentResolver) {
}
create(cp) {
this.resolver.resolveComponent(cp)
.then(factory => {
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
this.vcRef.createComponent(factory, 0, injector, []);
let ch = this.vcRef.createComponent(factory, 0, injector, []).instance;
ch.model = this.model;
});
}
ngOnChanges() {
if (!this.model) return;
switch (this.model.type) {
case 'checkbox':
this.create(CheckboxComponent);
break;
case 'checkboxlist':
this.create(CheckboxListComponent);
break;
case 'datepicker':
this.create(DatePickerComponent);
break;
default:
break;
}
}
}
Em seguida, carreguei essa diretiva na minha página como esta:
<div ctrl-factory *ngFor="let child of page.childrens" [model]="child"></div>
Porém, após a atualização da versão final do rc5 para a 2.0.0, o resolvedor não existe mais, foi substituído pelo compilador.
Encontrei muitos lugares mostrando como carregá-lo usando códigos diferentes, mas todos muito complexos e não consegui fazê-lo funcionar.
Veja isso por exemplo:Como posso usar / criar um modelo dinâmico para compilar o componente dinâmico com o Angular 2.0?
Parece mais específico para esse cenário, o meu só preciso carregar o componente e definir um @Input chamado model.
Uma coisa quando eu estava tentando, tive que criar dinamicamente um módulo para cada componente e adicionar o componente a ele. Mas então eu tive problemas dizendo que o componente estava sendo configurado em mais de um módulo, tente remover em algum lugar um que não esteja funcionando.
A maior parte do código mostrado, recebo deste link:http://blog.lacolaco.net/post/dynamic-component-creation-in-angular-2-rc-5/
E fez algumas mudanças.
Atualizar
Consigo fazê-lo funcionar, usando a seguinte abordagem:
O método de criação foi alterado para
private create(cp) {
@NgModule({
imports: [BrowserModule, ControlsModule],
declarations: []
})
class DynamicModule {}
this.compiler.compileModuleAndAllComponentsAsync(DynamicModule)
.then(({componentFactories}) => {
const compFactory = componentFactories.find(x => x.componentType === cp);
const injector = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
const cmpRef = this.vcRef.createComponent(compFactory, 0, injector, []);
cmpRef.instance.model = this.model;
});
}
Na maioria dos lugares que encontrei, crie o Component e defina-o como DynamicModule, o problema é quando você já declara o mesmo componente em um módulo diferente, o angular vai reclamar. A solução no meu caso foi importar o meu ControlsModule que possui todos os meus controles sendo exportados.