Angular 2 : Loading components dynamically from a service response

标签 angular

我知道这不是最好的解决方案,但我希望能够从 JSON 响应动态加载组件,大致如下:

应用组件

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1> {{component.title}} {{component.selector}}',
    providers: [AppService],
    directives: [ExampleComponent]
})
export class AppComponent implements OnInit {

    component:{};

    constructor(
        private _appService: AppService) {
    }

    ngOnInit() {
        this.component = this._appService.getComponent();
    }
}

应用服务

@Injectable()
export class AppService {

    component = {
        title: 'Example component',
        selector: '<example></example>'
    }

    getComponent() {
        return this.component;
    }
}

示例组件

@Component({
    selector: 'example',
    template: 'This a example component'
})
export class ExampleComponent  {
}

如果我运行这个例子,我的输出是<example></example>但它实际上并不渲染组件。我也试过使用 [innerHtml]="component.selector" ,但这也没有用。有没有人有想法或建议?

最佳答案

更新

创建组件的代码发生了一些变化。 可以在 Angular 2 dynamic tabs with user-click chosen components 中找到一个工作示例


要动态插入组件,您可以使用 ViewContainerRef.createComponent()

对于声明式方法,您可以使用辅助组件,例如

@Component({
  selector: 'dcl-wrapper',
  template: `<div #target></div>`
})
export class DclWrapper {
  @ViewChild('target', {read: ViewContainerRef}) target;
  @Input() type;
  cmpRef:ComponentRef;
  private isViewInitialized:boolean = false;

  constructor(private resolver: ComponentResolver) {}

  updateComponent() {
    if(!this.isViewInitialized) {
      return;
    }
    if(this.cmpRef) {
      this.cmpRef.destroy();
    }
   this.resolver.resolveComponent(this.type).then((factory:ComponentFactory<any>) => {
      this.cmpRef = this.target.createComponent(factory)
    });
  }

  ngOnChanges() {
    this.updateComponent();
  }

  ngAfterViewInit() {
    this.isViewInitialized = true;
    this.updateComponent();  
  }

  ngOnDestroy() {
    if(this.cmpRef) {
      this.cmpRef.destroy();
    }    
  }
}

另见 Angular 2 dynamic tabs with user-click chosen components

在你的例子中你可以像这样使用它

@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1> {{component.title}} <dcl-wrapper [type]="component.type"></dcl-wrapper>',
    providers: [AppService],
    directives: [ExampleComponent]
})
export class AppComponent implements OnInit {

    component:{};

    constructor(
        private _appService: AppService) {
    }

    ngOnInit() {
        this.component = this._appService.getComponent();
    }
}
import {ExampleComponent} from './example.component.ts';

@Injectable()
export class AppService {

    component = {
        title: 'Example component',
        type: ExampleComponent
    }

    getComponent() {
        return this.component;
    }
}

关于 Angular 2 : Loading components dynamically from a service response,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37540197/

相关文章:

typescript - Angular2/RxJS - 从 Http observable 获取数据后更新变量

javascript - typescript :仅测试 Nan、null 和 undefined

angular - 如何使用 ionic native 文件打开器打开(doc、ppt、xlsx、pdf、jpg、png)文件

javascript - 检查事件在路由 Angular 后引发两次

javascript - Angular 4 没有在我的子组件中渲染我的 ID

angular - 如何在 TypeScript 中将接口(interface)作为参数传递并获取匿名回调?

angular - 以编程方式选择一行 ag-grid + angular 2

css - 设置 Angular 组件的全高

angular - 你的全局 Angular CLI 版本高于本地版本

angular - 使用 Angular 2 的 Http 的替代类提供程序