绑定在动态加载的组件中不起作用

Bindings not working in dynamically loaded component

本文关键字:组件 不起作用 加载 动态 绑定      更新时间:2023-09-26

我遇到一个问题,如果我动态加载一个组件,模板中的绑定都不适合我。此外,ngOnInit方法永远不会被触发。

loadView() {
    this._dcl.loadAsRoot(Injected, null, this._injector).then(component => {
      console.info('Component loaded');
    })
  }

动态加载组件

import {Component, ElementRef, OnInit} from 'angular2/core'
declare var $:any
@Component({
    selector: 'tester',
    template: `
      <h1>Dynamically loaded component</h1>
        <span>{{title}}</span>
    `
})
export class Injected implements OnInit {
    public title:string = "Some text"
    constructor(){} 
    ngOnInit() {
      console.info('Injected onInit');
    }
}

这是我第一次使用动态加载的组件,所以我认为可能是试图错误地实现它。

这是一个演示这个问题的庞克。如有任何帮助,我们将不胜感激。

正如Eric Martinez所指出的,这是一个与loadAsRoot的使用有关的已知错误。建议的解决方法是使用loadNextToLocationloadIntoLocation

对我来说,这是有问题的,因为我试图动态加载的组件是一个位于fixed css位置的组件内部的模式对话框。我还希望能够从任何组件加载模态,并将其注入DOM中的同一位置,而不管它是从哪个组件动态加载的。

我的解决方案是使用forwardRef将我的根AppComponent注入到想要动态加载我的模态的组件中。

constructor (
    .........
    .........
    private _dcl: DynamicComponentLoader,
    private _injector: Injector,
    @Inject(forwardRef(() => AppComponent)) appComponent) {
    this.appComponent = appComponent;
}

在我的AppComponent中,我有一个返回应用程序的ElementRef 的方法

@Component({
    selector: 'app',
    template: `
        <router-outlet></router-outlet>
        <div #modalContainer></div>
    `,
    directives: [RouterOutlet]
})
export class AppComponent {
    constructor(public el:ElementRef) {}
    getElementRef():ElementRef {
        return this.el;
    }
}

回到我的另一个组件(我想从中动态加载模态的组件),我现在可以调用:

this._dcl.loadIntoLocation(ModalComponent, this.appComponent.getElementRef(), 'modalContainer').then(component => {
    console.log('Component loaded')
})

也许这将帮助其他有类似问题的人。

无需从DOM中清除组件实例。使用angular2/core包中的"componentRef"来创建和处理组件实例。使用show()在所需位置加载模态组件,使用hide()在第二次调用loadIntoLocation之前处理组件实例。

例如:

@Component({
  selector: 'app',
  template: `
    <router-outlet></router-outlet>
    <div #modalContainer></div>
 `,
  directives: [RouterOutlet]
})
export class AppComponent {
  private component:Promise<ComponentRef>;
  constructor(public el:ElementRef) {}
  getElementRef():ElementRef {
    return this.el;
  }
  show(){
    this.component = this._dcl.loadIntoLocation(ModalComponent,this.appComponent.getElementRef(), 'modalContainer').then(component => {console.log('Component loaded')})
  }
  hide(){
    this.component.then((componentRef:ComponentRef) => {
      componentRef.dispose();
      return componentRef;
    });
  }
}