angualrjs动态加载分析

作者:胡兵

动态加载js和css是很容易的,在head中插入script或者link标签就可以办到

function loadjscssfile(filename,filetype,loadfun){
    if(filetype == "js"){
        var fileref = document.createElement('script');
        fileref.setAttribute("type","text/javascript");
        fileref.setAttribute("src",filename);
    }else if(filetype == "css"){
        var fileref = document.createElement('link');
        fileref.setAttribute("rel","stylesheet");
        fileref.setAttribute("type","text/css");
        fileref.setAttribute("href",filename);
    }
   if(typeof fileref != "undefined"){
        fileref.onload = function () {
            if(loadfun){loadfun();}
        };
        document.getElementsByTagName("head")[0].appendChild(fileref);
    }
}
// loadjscssfile("do.js","js",function(){});
// loadjscssfile("test.css","css",function(){});

angularjs启动后,再加载的js,js代码可以执行,但js里面按常规方法定义的module,以及定义在该module上的controller、service、directive、filter等无法生效,原因是这些module无法被加载。也就是说需要一次性把所有的js全部加载才能正常工作。

ngInclude的原理:将html文件(也就是模板文件)作为一种资源,通过xhr请求下来,将内容作为dom元素插入父dom元素中,然后使用$compile服务,编译连接后就能正常工作了,前提是html里面引用的controller、service、directive等必须先定义好了,引用的样式也一样需要先定义好,这也就解释了为什么我们需要先通过requirejs把所有的js全部加载了,并且在还把所有的css文件全部也加载了

ngRoute以及angular-ui-router和ngInclude的原理大致相同,如uiView这个指令会根据当前是什么state,然后去加载对应的模板文件,一样的需要编译连接dom元素

我们基于cordova+ionic框架的应用,如果在启动时候加载所有的js,就会在一些性能不好的android手机上面启动时候慢,闪屏等,不是很好的体验;另外我们也有将一个模块打成zip包,下载到客户端,再解压缩使用的需求,如果按以前的方式,需要重定向才能正常工作,重定向就会重新加载,加载慢的问题又会显现出来。

我们想做到的是,我需要哪个模块就加载那个模块的js、css、html,如果那个模块已经加载过就不需要再加载了;这就是后加载技术,也就是动态加载技术。


angularjs动态加载方法,那么传统定义module、controller、service等方法不适用了;需要说明一下的是无论你定义多少module,所有module里面定义的service都统一放在一个实例注入器里面的,所有controller也是放在一处的;因angularjs没暴露模块加载方法,模块加载函数是一个内部方法,外部无法访问,只有在启动创建注入器才内部调用,一个app也只能有一个注入器。因此不再定义module了,命名空间仅限于controller、service、directive的工厂函数,不像我们以前还有有requirejs、module共三层命名空间;动态定义controller、service、directive、filter的方法如下:

  • 定义控制器

$controllerProvider.register(name, constructor);

  • 定义服务

$provide.provider(name, provider);
$provide.factory(name, $getFn);
$provide.service(name, constructor);
$provide.value(name, value);
$provide.constant(name, value);
$provide.decorator(name, decorator);

  • 定义filter

$filterProvider.register(name, constructor);

  • 定义directive

$compileProvider.directive(name, directiveFactory);

上面的定义方法就是你使用module来定义这些方法的背后实现方法,经我实践是切实可行的,结合动态js加载,就可以实现angualrjs的动态加载了。缺点就是你以后定义controller、service、directive需要改变方法了,本质还是一样的,思路更是一样的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值