kittencup / angular2-ama-cn

angular2 随便问
691 stars 101 forks source link

Angular2 如何手动渲染一个组件 #21

Open Coohack opened 8 years ago

Coohack commented 8 years ago

如题:angular2如何手动渲染一个组件

kittencup commented 8 years ago

可使用DynamicComponentLoader对象手动渲染一个组件 源码在 src/core/linker/dynamic_component_loader.ts,提供了3种不同机制的load

loadAsRoot

不同平台global view代表的内容不一样,在浏览器上global view是Dom文档。 在global view找到指定的selector,渲染组件并插入到匹配selector元素内部

Dialog组件插入class=".dialog"的元素内部

dynamicComponentLoader.loadAsRoot(Dialog,'.dialog',injector);

结果

<app>
    <div class="dialog">
        Dialog...
    </div>
</app>

loadAsRoot是用于创建host element , 所以在创建时需要传入injector,通过这个injector才能创建出host elementinjector, 如果对Angular 2 分级依赖注入不了解的,可以看这篇翻译的官方文档

loadIntoLocation

将组件插入到指定的elementRef中的anchorName后面

 this.dynamicComponentLoader.loadIntoLocation(Dialog,elementRef,'dialog')

结果

<app>
    <div #dialog></div>
    Dialog...
</app>

loadNextToLocation

将组件插入到指定的elementRef对应的组件后面

 this.dynamicComponentLoader.loadNextToLocation(Dialog,elementRef)
<app>
     <div #dialog></div>
</app>
Dialog...

总结

可以根据自己的需求使用不同的机制手动加载组件,加载组件全部是异步处理的,所以这3个方法都会返回一个promise

this.dynamicComponentLoader
    .loadNextToLocation(Dialog,elementRef)
    .then((containerRef)=>{

    })

示例

import {Component,DynamicComponentLoader,ElementRef} from 'angular2/core';

@Component({
    selector: 'dialog',
    directives: [],
    template: `
        <p>dialog</p>
    `,
})
export class Dialog {

}

@Component({
    selector: 'app',

    template: `
        <button (click)="loadAsRoot()">loadAsRoot</button>
        <button (click)="loadIntoLocation()">loadIntoLocation</button>
        <button (click)="loadNextToLocation()">loadNextToLocation</button>

        <div class="dialog" #dialog>

        </div>

    `,
})
export class App {

    constructor(public dynamicComponentLoader:DynamicComponentLoader,
                public injector:Injector,
                public elementRef:ElementRef) {

    }

    loadAsRoot() {
        this.dynamicComponentLoader.loadAsRoot(Dialog, '.dialog', this.injector);
    }

    loadIntoLocation() {
        this.dynamicComponentLoader.loadIntoLocation(Dialog,this.elementRef,'dialog')
    }

    loadNextToLocation() {
        this.dynamicComponentLoader.loadNextToLocation(Dialog,this.elementRef)
    }

}

官方 Angular 2 Materail 示例

https://github.com/angular/angular/blob/master/modules%2Fangular2_material%2Fsrc%2Fcomponents%2Fdialog%2Fdialog.ts#L63

Coohack commented 8 years ago

thanks a lot

F2EVarMan commented 8 years ago

请问手动渲染的组件 如何销毁呢

kittencup commented 8 years ago

如何销毁 可看 https://github.com/kittencup/angular2-ama-cn/issues/73