3

i used viewContainerRef.createComponent to load dynamic component into root component(.....) ,but actual it append the wrong place,

enter image description here

my code:

-----app.compoment.ts-----

export class AppComponent { 
   private viewContainerRef:ViewContainerRef;
   public constructor(viewContainerRef:ViewContainerRef) {
    this.viewContainerRef = viewContainerRef;
  }
}

-----a.service.ts------

@Injectable()
export class ModalService {
  private viewContainerRef:ViewContainerRef;
    constructor(applicationRef: ApplicationRef, injector: Injector,private compiler: ComponentResolver) { 
        var classOfRootComponent = applicationRef.componentTypes[0];
        // this is an instance of application bootstrap component
        var appInstance = injector.get(classOfRootComponent);
        this.viewContainerRef= appInstance.viewContainerRef;
    }
    alert() {console.log(this.viewContainerRef);
        this.compiler.resolveComponent(ModalComponent)
        .then(
            (factory) =>
            this.viewContainerRef.createComponent(factory, 0, this.viewContainerRef.injector)
        ).then((componentRef) => {
                return componentRef;
            }
        );
    }
}
gligoran
  • 3,267
  • 3
  • 32
  • 47
keyiis
  • 59
  • 1
  • 5

1 Answers1

4

This is "as designed". See also this discussion https://github.com/angular/angular/issues/9035

If you want <custom-modal> to be inserted inside <my-app> add a target element into the template of <my-app> and use this as target.

You need to pass it from the AppComponent to the ModalService like

@Component({
  selector: 'my-app',
  template: `<div #target></div>`
})
export class AppComponent {
  @ViewChild('target', {read: ViewContainerRef}) viewContainerRef:ViewContainerRef;

  constructor(private modalService:ModalService) {}

  ngAfterViewInit() {
    this.modalService.viewContainerRef = this.viewContainerRef;
  }
}

This PR is about a similar use case and might interest you https://github.com/angular/angular/pull/9393

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • thks reply! i not familiar with stackoverflow. i won't inject ModalService in root component, I wonder that i already get ViewContainerRef in ModalService,but why can't get it injector? – keyiis Jun 28 '16 at 09:06
  • I don't really understand you question. You get `ViewContainerRef` from the root component and adding to it will create siblings of `ViewContainerRef`. If you want to add inside the root element, you need a `ViewContainerRef` from an element inside the root elements template. My answer shows how to get such a `ViewContainerRef`. – Günter Zöchbauer Jun 28 '16 at 09:07
  • In other words,can i get first child(my-app) ViewContainerRef from the root's viewContainerRef in service?Because I didn't want to contaminate the root component(In addition to set this.viewContainerRef). – keyiis Jun 29 '16 at 05:51
  • Currently not as far as I know. – Günter Zöchbauer Jun 29 '16 at 05:54