Angualr2动态组件加载器

在Angular2中,组件是我们建立并指定页面上的元素和逻辑的主要途径。而我们通常加载它在其中包含了一些条件,使其加载动态标记的标签。

但也有情况下,我们不知道在编译时DOM结构。在这种情况下,我们必须对任意位置的需求添加组件,因此我们使用DynamicComponentLoader动态加载的组件。在这种情况下,我们将能够在指定的位置来实例化一个组件,它连接到一个视图。

beta16之前,DynamicComponentLoader有三种方法,升级后删除了一种方法

loadAsRoot:

创建了一个组件的一个实例并将其附加到的第一个元素,该组件的选择相匹配的DOM。

import {Component, DynamicComponentLoader, Injector ,ComponentRef} from ‘@angular/core‘;
import {CommonComponent} from ‘./common.component‘;
@Component({
    template: `
    <div class="box">
        <button (click)="form()">View Form</button>
        <div id="form">Welcome..! Here form component will be loaded.</div>
    </div>
    `,
    styles : [`
        .box {padding-top:2rem;}
    `]
})
export class LoadAsRoot {
    constructor(public dcl:DynamicComponentLoader, public _injector:Injector){}
    form(){
      this.dcl.loadAsRoot(CommonComponent,"#form",this._injector)
            .then((ComponentRef:ComponentRef) => {
                console.log(ComponentRef);
            })
    }
}

loadNextToLocation

创建一个组件并将其添加到当前组件的后面next siblings

loadNextToLocation.ts

import {Component, DynamicComponentLoader, Injector, ViewContainerRef ,ComponentRef} from ‘@angular/core‘;
import {Common} from ‘./common‘;

@Component({
    selector: ‘my-app‘,
    providers: [],
    template: `

    <div *ngIf="user">
        <div>姓名:{{user.username}}</div>
        <div>年龄:{{user.age}}</div>
    </div>
    <div *ngIf="!user">
        <div><button (click)="loadNext()">添加数据</button></div>
        <div>暂无数据</div>
    </div>
  `,
    directives: []
})
export class LoadNextToLocation {
    public user: any;
    constructor(public dcl:DynamicComponentLoader, public _injector:Injector, public _elementRef: ViewContainerRef) {}

    loadNext(){
        this.dcl.loadNextToLocation(Common,this._elementRef)
            .then((ComponentRef:ComponentRef) => {
                let instance = ComponentRef.instance;
                instance.ref = ComponentRef
                instance.name = ‘添加数据‘;
                instance.finally.subscribe((user)=>{
                    ComponentRef.destroy();
                    this.user = user;
                })
                return ComponentRef;
            })
    }
}

common.ts

import {Component ,Input , Output, ComponentRef , EventEmitter } from ‘@angular/core‘;
@Component({
    template: `
        <div>
            <div>{{name}}</div>
            <div><input type="text"  [(ngModel)]="data.username" placeholder="用户名"></div>
            <div><input type="text"  [(ngModel)]="data.age" placeholder="年龄"></div>
            <div><button (click)="destory()">提交</button></div>
            <div><button (click)="cancel()">取消</button></div>
        </div>
    `
})
export class Common{
    private  data: {username: string, age: string} = {
        username: ‘‘,
        age: ‘‘
    }

    @Input() name: string;
    @Input() ref: ComponentRef;
    @Output() finally = new EventEmitter();

    cancel(){
        this.ref.destroy();
        console.log(`cancel`)
    }

    destory(){
        console.log(this.data);
        this.finally.emit(this.data);
    }
}

组件间传递数据通过@input 和 @output

ComponentResolver也可以动态加载组件

import {Component, DynamicComponentLoader,ComponentResolver Injector, ViewContainerRef ,ComponentRef} from ‘@angular/core‘;
import {PagesComponent} from ‘./pages.component‘;

@Component({
    selector: ‘my-app‘,
    providers: [],
    template: `

    <div *ngIf="user">
        <div>姓名:{{user.username}}</div>
        <div>年龄:{{user.age}}</div>
    </div>
    <div *ngIf="!user">
        <div><button (click)="loadNext()">添加数据</button></div>
        <div>暂无数据</div>
    </div>
  `,
})
export class LoadNextToLocation {
    public user: any;
    constructor(public dcl:DynamicComponentLoader, public viewContainerRef: ViewContainerRef , compiler: ComponentResolver ) {
        compiler.resolveComponent(PagesComponent).then((factory) =>
            viewContainerRef.createComponent(factory, 0, viewContainerRef.injector)).then((ComponentRef:ComponentRef) => {
            let instance = ComponentRef.instance;
            instance.ref = ComponentRef
            instance.name = ‘添加数据‘;
            instance.finally.subscribe((user)=>{
                ComponentRef.destroy();
                this.user = user;
            })
            return ComponentRef;
        });
    }

    loadNext(){
        this.dcl.loadNextToLocation(PagesComponent,this.viewContainerRef)
            .then((ComponentRef:ComponentRef) => {
                let instance = ComponentRef.instance;
                instance.ref = ComponentRef
                instance.name = ‘添加数据‘;
                instance.finally.subscribe((user)=>{
                    ComponentRef.destroy();
                    this.user = user;
                })
                return ComponentRef;
            })
    }
}
时间: 2024-10-28 11:47:24

Angualr2动态组件加载器的相关文章

react 动态组件加载器

在进行react项目,特别是后台管理的项目开发中,表单.提示框等弹出组件的应用是相当广泛的. 而这些弹框组件的状态比如开启.关闭以及内部显示的内容通常都要依靠父级组件的state进行管理. 但是当在一个页面组件中大量的使用到这些弹框的时候,对他们的状态管理会有非常严重的问题,每一个弹框组件都需要相应的state状态控制,这些状态信息一个一个的积累下来会造成state对象的异常臃肿,对代码的维护管理有很大的负面影响. 为了解决这个问题,最好不要将这些组件写死在父级组件里面,不用state状态控制打

使用js加载器动态加载外部Javascript文件

今天在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js 1 var MiniSite=new Object(); 2 /** 3 * 判断浏览器 4 */ 5 MiniSite.Browser={ 6 ie:/msie/.test(window.navigator.userAgent.toLowerCase()), 7 moz:/gecko/.test(window.navigator.userAgent.toLowerCase()), 8 opera:/o

EasyUI基础入门之Easyloader(加载器)

在了解完easyui的parser(解析器)之后,接下来就是easyloader(简单加载器)的学习了. 什么是EasyLoader 正如其名字一样easyloader的作用是为了动态的加载组件所需的js文件,这体现了EasyUI作为轻量级框架对性能的合理掌握(可以动态的加载所需组件),不过一般而言很少使用到easyloader(会给使用者带来一定的难度).那么使用EasyLoader的场景有哪些呢? EasyLoader使用场景 出于性能的考虑,不一次性的加载easyui核心js.css文件,

在Java Web Project中实现Vue异步组件加载

背景 最近看上了ElementUI(Vue实现)用来实现一个管理系统Demo,其中一个最常见的需求就是左侧导航不动,右侧主页块在点击导航菜单时动态更新,如下图所示:之前的实现方案是右边嵌入一个iframe,动态更改iframe的url即可,现在既然用了Vue咱也试试单页,是不是显得更优雅.接着就接触到了vue-router.组件.异步组件这些关键字,本以为把页面定义为xxx.vue放到webapp下,然后告诉vue-router去加载就好了,最后发现自己想简单了,思维模式还停留在Java Web

js前端模块化之加载器原理解析(一)

先来说一下前端模块化的价值:引用模块此处有详细的介绍,可以自行前往观看. 一.总结如下优点: (1)解决命名冲突(2)烦琐的文件依赖(3)模块的版本管理(4)提高可维护性(5)前端性能优化(6)跨环境共享模块 二.加载器的基本思路: 如何去定义我们的模块? 如何将我们定义的模块去合并? 我们想一下,如果我们正常的引用入js到页面我们需要做神马事情,是否是使用:<script type="text/javascript" src="xxx"></sc

C编译器、链接器、加载器详解

摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接.编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程.链接是把目标文件.操作系统的启动代码和用到的库文件进行组织形成最终生成可加载.可执行代码的过程. 过程图解如下: 预处理器:将.c 文件转化成 .i文件,使用的gcc命令是

【模块化编程】理解requireJS-实现一个简单的模块加载器

在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ...... 为了深入了解加载器,中间阅读过一点requireJS的源码,但对于很多同学来说,对加载器的实现依旧不太清楚 事实上不通过代码实现,单单凭阅读想理解一个库或者框架只能达到一知半解的地步,所以今天便来实现一个简单的加载器 加载器原理分析 分与合 事实上,一个程序运行需要完整的模块,以下代码为例: 1

《你必须知道的.NET》读书实践:一个基于OO的万能加载器的实现

此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.关于万能加载器 简而言之,就是孝顺的小王想开发一个万能程序,可以一键式打开常见的计算机资料,例如:文档.图片和影音文件等,只需要安装一个程序就可以免去其他应用文件的管理(你让其他耗费了巨资打造的软件情何以堪...),于是就有了这个万能加载器(FileLoader). 初步分析之后,小王总结了这个万能加载器的功能点如下: (1)能够打开常见文档类资料:txt.word.pdf.visio等: (2)能够打开

Ogre 编辑器二(用Ogre的地形组件加载天龙八部地形)

主界面如上文设计完成后,场景刚开始添加了是Ogre例子里的,发现场景里实物太少,于是想到直接把天龙的场景拿下来,天龙网上有源码,参考了下,把天龙的地形用Ogre的地形组件完成了下,如下是效果图: 因为主要是加载地形,然后只是简单加载了静态模型,因此场景看着比较简陋,再者因为上传的图片限制,场景复杂后根本传不上来. 天龙的地形还是比较简单的,如下是天龙的pingpan.terrain简化后的内容. <?xml version="1.0" encoding="UTF-8&q