Estoy tratando de crear un componente Grid personalizado, en el que quiero renderizar / pasar otros componentes. Creé un componente Grid y lo estoy cargando dinámicamente en mi dashboard.component.ts.

Aquí está la plantilla de mi Grid.

<div nz-row *ngFor="let row of grid; index as i;">
    <div nz-col *ngFor="let col of row; index as j;">
      <div>
        <ng-template name="{{i}}{{j}}"></ng-template>
      </div>
    </div>
</div>

La directiva.

@Directive({
  selector: 'ng-template[name]'
})
export class CustomGridDirective {
  @Input() name: string;

  constructor(public viewContainerRef: ViewContainerRef) { }
}

Mi custom-grid.component.ts,

export class CustomGridComponent implements OnInit {

  @Input() grid: any;
  @ViewChildren(CustomGridDirective) gridContainer: QueryList<CustomGridDirective>;
  
  constructor() {}
  
  ngOnInit() {
  }
}

Dashboard.component.ts, donde estoy cargando dinámicamente mi componente Grid.

async customGrid(){
  const {CustomGridComponent} = await import('../custom-grid/custom-grid.component');
  const customGridFactory = this.cfr.resolveComponentFactory(CustomGridComponent);
  let {instance} = this.anchor1.createComponent(customGridFactory, null, this.injector);
  instance.grid = [
    ['1', '2', '3']
  ]
  return instance
}

ngAfterViewInit() {
  this.customGrid().then( component => console.log(component.gridContainer));
}

Ahora, no puedo acceder a component.gridContainer ni siquiera a component.grid. Ambos regresan, undefined.

Digamos que tengo un dashboard-widget-1.component, ¿cómo lo renderizo dinámicamente dentro del componente de cuadrícula personalizada? Estaba tratando de acercarme a la lista de consultas de ViewChildren e intentar representar el componente en su interior.

Pero obtengo component.gridContainer y component.grid, ambos, como indefinidos. ¿Cómo puedo renderizar componentes dinámicamente, como dashboard-widget-1.component y dashboard-widget-2.component en mi componente Grid (que he cargado dinámicamente)?

Estoy estancado desde hace días, cualquier ayuda será muy apreciada.

1
Juggernaut 3 ago. 2020 a las 07:10

1 respuesta

La mejor respuesta

Es undefined porque todavía no se ha ejecutado ningún ciclo de detección de cambios en ese componente.

componentRef.changeDetectorRef.detectChanges();

const widgetFactory = this.cfr.resolveComponentFactory(CustomWidgetComponent);
instance.galleryContainer.forEach(target => {
  target.viewContainerRef.createComponent(widgetFactory, null, this.injector)
});

Además, si desea cargar un componente de forma diferida, asegúrese de que el archivo importado contenga NgModule que describe todas las declaraciones dependientes:

custom-grid.components.ts

@Component({
  ...
})
export class CustomGridComponent implements OnInit {
  ...
}
... 
@NgModule({
  imports: [
    CommonModule,
  ],
  declarations: [CustomGridComponent, CustomGridDirective],
})
export class CustomGridModule { }

bifurcado Stackblitz

1
yurzui 3 ago. 2020 a las 05:55