【问题标题】:Angular2: Loading components dynamically from a service responseAngular2:从服务响应动态加载组件
【发布时间】:2016-05-31 08:06:17
【问题描述】:

我知道这不是最好的解决方案,但我希望能够从 JSON 响应动态加载组件,类似于以下内容:

app.component

@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();
    }
}

app.service

@Injectable()
export class AppService {

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

    getComponent() {
        return this.component;
    }
}

example.component

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

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

【问题讨论】:

    标签: angular


    【解决方案1】:

    更新

    创建组件的代码发生了一些变化。 在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;
        }
    }
    

    【讨论】:

    • @GünterZöchbauer 有没有办法用组件替换目标?
    • 我不这么认为。
    • @Geo 是否可以正常工作,这是否意味着您可以从远程调用返回组件中将组件加载为 json 或者我没有得到什么?
    • @GünterZöchbauer 不确定我得到你的答案
    猜你喜欢
    • 2017-01-10
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    相关资源
    最近更新 更多