Próbuję wykonać niestandardowy komponent sieci, w którym chcę, aby uczynić / przejść inne komponenty. Stworzyłem komponent siatki i dynamicznie ładuję go w moim dashboard.component.ts.

Oto szablon mojej siatki.

<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>

Dyrektywa.

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

  constructor(public viewContainerRef: ViewContainerRef) { }
}

Mój custom-grid.component.ts,

export class CustomGridComponent implements OnInit {

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

Dashboard.component.ts, gdzie dynamicznie ładuję mój komponent siatki.

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));
}

Teraz nie jestem w stanie uzyskać dostępu do component.gridContainer, a nawet component.grid. Zarówno powrót, undefined.

Powiedz, że mam dashboard-widget-1.component, jak mogę dynamicznie renderować w komponencie Custom-Grid? Próbowałem podejść do listy zapytania ViewSchildren i spróbować uczynić komponentem wewnątrz.

Ale dostaję component.gridContainer i component.grid, zarówno jako niezdefiniowany. Jak mogę dynamicznie renderować komponentów, takich jak dashboard-widget-1.component i dashboard-widget-2.component w moim komponencie siatkowym (które mam dynamicznie załadowane)?

Utknąłem od dni, każda pomoc zostanie bardzo doceniana.

1
Juggernaut 3 sierpień 2020, 07:10

1 odpowiedź

Najlepsza odpowiedź

To jest undefined, ponieważ nie było jeszcze cyklu wykrywania zmian w tym komponencie.

componentRef.changeDetectorRef.detectChanges();

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

Również jeśli chcesz, aby leniwy załadować komponent, upewnij się, że importowany plik zawiera ngmodule, który opisuje wszystkie uzależnione deklaracje:

custom-grid.components.ts

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

rozwidlony Stackblitz

1
yurzui 3 sierpień 2020, 05:55