Add dynamically created custom Angular components to layout in Nativescript


I am trying to add a dynamically created custom Angular component to a GridLayout in NativeScript. I know how I can dynamically add the default non-Angular NativeScript components such a Label from tns-core-modules/ui/label, but it seems to be working different with Angular components.

I was following this post which describes how to do it in pure Angular. It seems to be almost working in NativeScript but not entirely. So far I am using a template like this:

 <GridLayout #grid>

and then in the code I am attempting something like below:

@ViewChild('grid') gridRef:ElementRef;

public ngAfterViewInit() {

  let grid = this.gridRef.nativeElement;
  grid.addRow(new ItemSpec(1, GridUnitType.AUTO));
  grid.addColumn(new ItemSpec(1, GridUnitType.STAR));

  let componentFactory = this.cfr.resolveComponentFactory(MyCustomComponent);
  let componentRef = componentFactory.create(this.vcr.injector, null, grid);
  componentRef.instance.myproperty = 'some value'; // pass input

  this.appRef.attachView(componentRef.hostView); // add to ng component tree for change detection

  const component = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0];

After the final step, I do see that the grid has allocated the required space that the component requires, but nothing shows. If I comment out the last step, then indeed that space that is reserved is gone. I also confirmed that the rootNodes array has only one element.

Anyone has any idea as to what I might be missing? I guess the question is how can I take an Angular view and convert it to a NativeScript view, so I can perform the grid.addChild and also the actions below to assign the newly created component to a specific row/column.

GridLayout.setRow(component,0); // fix to grid row
GridLayout.setColumn(component,index); // fix to grid column

How will that then work?


P.S. I have opened this issue on Stack Overflow as well if someone prefers to answer there.


Yes, it works differently with Angular components. It’s Angular’s rule and that’s how it understands components.

Can you create Playground with this?


@manojdcoder Sure, here is the link to the playground project.

Now I also understand why extending ui/core/view didn’t give me the results I was expecting (like inheriting properties from NS Core’s View).

  1. From row / col values won’t be assigned here as it’s a Angular component. It may be passed as input like you do for text property already.
<GridLayout #grid columns="auto" rows="auto">
        <MyLabel row="0" col="0" text="Static MyLabel"></MyLabel>
  1. Each Angular component is wrapped with a ViewBase, not sure how to actually access it. May be someone from {N} Angular project can answer it.