0

In Parent Component.ts

  @ViewChild('dynamic', {
    read: ViewContainerRef
  }) viewContainerRef: ViewContainerRef;

In HTML code

<div cdkDropList class="example-container" (cdkDropListDropped)="drop($event)">
  <div class="example-box" *ngFor="let item of testSelector" cdkDrag>
    <div class="title">{{item.key}}</div>
    <div class="content" [innerHTML]="item.value | safeHtml">
    </div>
  </div>
</div>
<ng-template #dynamic></ng-template>

This work fine but when nested inside dive

<div cdkDropList class="example-container" (cdkDropListDropped)="drop($event)">
  <div class="example-box" *ngFor="let item of testSelector" cdkDrag>
    <div class="title">{{item.key}}</div>
    <div class="content" [innerHTML]="item.value | safeHtml">
       <ng-template #dynamic></ng-template>
    </div>
  </div>
</div>

viewContainerRef is undefined?

Component.ts

@Component({
 ....
})
export class TestComponent implements OnInit, AfterViewInit {

  @ViewChild('dynamic', {
    read: ViewContainerRef
  }) viewContainerRef: ViewContainerRef;

  constructor(@Inject(Service) private service) {
  }

  ngAfterViewInit() {
    this.service.setRootViewContainerRef(this.viewContainerRef);
    this.service.addDynamicComponent();
  }
}

and service.ts

@Injectable()
export class Service {
    factoryResolver: any;
    rootViewContainer: any;
    constructor(
        @Inject(ComponentFactoryResolver)
        factoryResolver) {
        this.factoryResolver = factoryResolver;
    }
    setRootViewContainerRef(viewContainerRef) {
        this.rootViewContainer = viewContainerRef;
    }
    addDynamicComponent() {
        const factory = this.factoryResolver
            .resolveComponentFactory(JobDashComponent);
        const component = factory
            .create(this.rootViewContainer.parentInjector);
        this.rootViewContainer.insert(component.hostView);
    }
}
7
  • Where are you trying to access the viewContainerRef? Commented Mar 14, 2019 at 12:07
  • In component.ts corresponding to this html code Commented Mar 14, 2019 at 12:09
  • Could you please add it here too? Commented Mar 14, 2019 at 12:13
  • I will add only the necessary content this component Commented Mar 14, 2019 at 12:15
  • It depends on where you are trying to access the viewContainerRef. Commented Mar 14, 2019 at 12:16

1 Answer 1

2

The viewContainerRef is undefined because you overwrite it with the [innerHTML] on it's parent tag

Instead of [innerHTML] you can use this

<div cdkDropList class="example-container" (cdkDropListDropped)="drop($event)">
  <div class="example-box" *ngFor="let item of testSelector" cdkDrag>
    <div class="title">{{item.key}}</div>
    <div class="content">
       {{item.value | safeHtml}}
       <ng-template #dynamic></ng-template>
    </div>
  </div>
</div>

Select more elements with same #id:

If you want to select every element with a specific #id then you can use QueryList.

The syntax would look like this

@ViewChildren('dynamic') viewContainerRefList: QueryList<ViewContainerRef>;

Then you can then work with it like with normal array if you apply .toArray() on it.

const array = viewContainerRefList.toArray();

Sign up to request clarification or add additional context in comments.

3 Comments

for example ngFor iterate over by Array length = 3 but only first element contains ng-template. Why this content is not added to all elements from array?
You mean why only the first ng-template is accessed by @ViewChild()?
I thought about it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.