Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get ViewContainerRef from Component

i want to create nested component in angular 4

this is chooser component

import {InputComponent} from './input/input.component'
import {BlockComponent} from './block/block.component'

export const FormChooser = {
  Block: BlockComponent,
  Input: InputComponent
}

this is component builder

const component = FormChooser[data.component]
const factory = this.Resolver.resolveComponentFactory(component)

const new_component = this.ViewContainerRef.createComponent(factory)

How to get new_component ViewContainerRef ? so i can use code like this

const another_new_component = new_component.createComponent(factory) // as ViewContainerRef

Thank you...

like image 424
Jimmy Wijaya Avatar asked Jul 08 '17 07:07

Jimmy Wijaya


People also ask

Which method of ViewContainerRef create an instance of a component?

Descriptionlink. Can contain host views (created by instantiating a component with the createComponent() method), and embedded views (created by instantiating a TemplateRef with the createEmbeddedView() method).

What is the difference between ElementRef TemplateRef and ViewContainerRef?

The simplest wrapper around a DOM element is ElementRef . For templates you have TemplateRef that allows you to create an embedded view. Host views can be accessed on componentRef created using ComponentFactoryResolver . The views can be manipulated with ViewContainerRef .

What can I use instead of ComponentFactoryResolver?

In Angular 13 the new API removes the need for ComponentFactoryResolver being injected into the constructor, like you did in your code. Now to dynamically create a component you have to use ViewContainerRef.

What is TemplateRef and ViewContainerRef in Angular?

A TemplateRef represents an <ng-template /> . <ng-template let-name let-date="dateNow">{{date}} - Hello {{name}}!</ng-template> An <ng-template /> itself will not do anything at all. We need a ViewContainerRef to insert the template somewhere.


2 Answers

You can inject ViewContainer in constructor of dynamic component

class BlockComponent {
  constructor(public vcRef: ViewContainerRef) {}
}

const factory = this.Resolver.resolveComponentFactory(BlockComponent)

const newComponentRef = this.ViewContainerRef.createComponent(factory);
const newComponentVcRef = newComponentRef.instance.vcRef; 

or use @ViewChild to get reference to ViewContainerRef

 template: '<ng-container #ref></ng-container>'
})
class BlockComponent {
  @ViewChild('ref') vcRef: ViewContainerRef;
}

const factory = this.Resolver.resolveComponentFactory(BlockComponent )

const newComponentRef = this.ViewContainerRef.createComponent(factory);
const newComponentVcRef = newComponentRef.instance.vcRef; 
like image 102
yurzui Avatar answered Oct 06 '22 09:10

yurzui


For Angular +8

import { InputNumberComponent } from '../input-number/input-number.component';
@Component({
  selector: 'app-dynamic-form',
  templateUrl: './dynamic-form.component.html',
  styleUrls: ['./dynamic-form.component.scss']
})
export class DynamicFormComponent implements OnInit {

  @ViewChild('ref', { read: ViewContainerRef }) vcRef: ViewContainerRef;
  constructor(private resolver: ComponentFactoryResolver) { }

  ngOnInit() {
    const comp = this.resolver.resolveComponentFactory(InputNumberComponent)
    this.vcRef.createComponent(comp)
  }

}
like image 26
feyzullahyildiz Avatar answered Oct 06 '22 09:10

feyzullahyildiz