详解angularjs利用ui-route异步加载组件


Posted in Javascript onMay 21, 2017

ui-route相比于angularjs的原生视图路由更好地支持了路由嵌套,状态转移等等。随着视图不断增加,打包的js体积也会越来越大,比如我在应用里面用到了wangeditor里面单独依赖的jquery就300多k。异步加载各个组件就很有必要。在这里我就以ui-route为框架来进行异步加载说明。

首先看一下路由加载文件

angular.module('webtrn-sns').config(['$stateProvider', function ($stateProvider) {
  $stateProvider.state({
      name: 'home.message',
      url: '/message',
      abstract: true,
      templateProvider: ['resources', function (resources) {
        return resources.template
      }],
      controllerProvider: ['resources', (resources)=> {
        return resources.controller
      }],
      onEnter: ['resources', (resources)=>resources.css.use()],
      onExit: ['resources', (resources)=>resources.css.unuse()],
      resolve: {
        resources: ()=> {
          return new Promise(
            resolve => {
              require([], () => {
                resolve({
                  css: require('./css/message_box.css'),
                  template: require('./html/message_box.html'),
                  controller: require('./js/message_box.js')
                })
              })
            }
          );
        }
      }
    }
  ).state({
      name: 'home.message.add_message',
      url: '/add_message?isReply&toUid&title',
      params: {isReply: null, toUid: null, title: null},
      templateProvider: ['resources', function (resources) {
        return resources.template
      }],
      controllerProvider: ['resources', (resources)=> {
        return resources.controller
      }],
      onEnter: ['resources', (resources)=>resources.css.use()],
      onExit: ['resources', (resources)=>resources.css.unuse()],
      resolve: {
        resources: ()=> {
          return new Promise(
            resolve => {
              require(['./js/message.js'], () => {
                resolve({
                  css: require('./css/add_message.css'),
                  template: require('./html/add_message.html'),
                  controller: require('./js/add_message.js')
                })
              })
            }
          );
        }
      }
    }
  )
}])

这个是路由状态的一个声明文件,name,url,param字段的方式不变,关键是看resolve这个部分。根据ui-route的resolve文档,resolve是为了给state或者controller进行自定义注入对象的。

下面是举出文档中关于resolve的例子:

$stateProvider.state('myState', {
   resolve:{
     // Example using function with simple return value.
     // Since it's not a promise, it resolves immediately.
     simpleObj: function(){
      return {value: 'simple!'};
     },
     // Example using function with returned promise.
     // This is the typical use case of resolve.
     // You need to inject any services that you are
     // using, e.g. $http in this example
     promiseObj: function($http){
      // $http returns a promise for the url data
      return $http({method: 'GET', url: '/someUrl'});
     },
     // Another promise example. If you need to do some 
     // processing of the result, use .then, and your 
     // promise is chained in for free. This is another
     // typical use case of resolve.
     promiseObj2: function($http){
      return $http({method: 'GET', url: '/someUrl'})
        .then (function (data) {
          return doSomeStuffFirst(data);
        });
     },    
     // Example using a service by name as string.
     // This would look for a 'translations' service
     // within the module and return it.
     // Note: The service could return a promise and
     // it would work just like the example above
     translations: "translations",
     // Example showing injection of service into
     // resolve function. Service then returns a
     // promise. Tip: Inject $stateParams to get
     // access to url parameters.
     translations2: function(translations, $stateParams){
       // Assume that getLang is a service method
       // that uses $http to fetch some translations.
       // Also assume our url was "/:lang/home".
       return translations.getLang($stateParams.lang);
     },
     // Example showing returning of custom made promise
     greeting: function($q, $timeout){
       var deferred = $q.defer();
       $timeout(function() {
         deferred.resolve('Hello!');
       }, 1000);
       return deferred.promise;
     }
   },
   // The controller waits for every one of the above items to be
   // completely resolved before instantiation. For example, the
   // controller will not instantiate until promiseObj's promise has 
   // been resolved. Then those objects are injected into the controller
   // and available for use. 
   controller: function($scope, simpleObj, promiseObj, promiseObj2, translations, translations2, greeting){
     $scope.simple = simpleObj.value;
     // You can be sure that promiseObj is ready to use!
     $scope.items = promiseObj.data.items;
     $scope.items = promiseObj2.items;
     $scope.title = translations.getLang("english").title;
     $scope.title = translations2.title;
     $scope.greeting = greeting;
   }
  })

我们可以看到resolve的对象是支持Promise的。

再回到我们之前的代码templateProvider和controllerProvider我们注入了resources的模板对象和controller对象,onEnter和onExit注入了css模块。

如果controller中依赖了服务怎么办的?

resolve: {
  resources: ()=> {
    return new Promise(
      resolve => {
        require(['./js/message.js'], () => {
          resolve({
            css: require('./css/add_message.css'),
            template: require('./html/add_message.html'),
            controller: require('./js/add_message.js')
          })
        })
      }
    );
  }
}

可以在require里面将服务注入,如代码中的message.js。而为了将服务进行异步加载我们不能用普通的.factory或者.service。而需要调用$provide.factory或者$provide.service

如果采用webpack进行编译打包的话就需要webpack.optimize.CommonsChunkPlugin的支持,这样可以对js进行拆分打包,达到异步加载js的目的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript中获取元素索引的函数
Sep 10 Javascript
基于jQuery的淡入淡出可自动切换的幻灯插件打包下载
Sep 15 Javascript
Js参数值中含有单引号或双引号问题的解决方法
Nov 06 Javascript
JS判断不能为空实例代码
Nov 26 Javascript
一段非常简单的js判断浏览器的内核
Aug 17 Javascript
JavaScript基本的输出和嵌入式写法教程
Oct 20 Javascript
js图片轮播手动切换效果
Nov 10 Javascript
探讨:JavaScript ECAMScript5 新特性之get/set访问器
May 05 Javascript
完美解决js传递参数中加号和&号自动改变的方法
Oct 11 Javascript
基于Vue实现可以拖拽的树形表格实例详解
Oct 18 Javascript
你知道JavaScript Symbol类型怎么用吗
Jan 08 Javascript
基于vue-draggable 实现三级拖动排序效果
Jan 10 Javascript
如何在AngularJs中调用第三方插件库
May 21 #Javascript
详解Angular-Cli中引用第三方库
May 21 #Javascript
Angular2安装angular-cli
May 21 #Javascript
Angular2使用Augury来调试Angular2程序
May 21 #Javascript
Angular2使用Angular-CLI快速搭建工程(二)
May 21 #Javascript
Angular2使用Angular CLI快速搭建工程(一)
May 21 #Javascript
jQuery获取单选按钮radio选中值与去除所有radio选中状态的方法
May 20 #jQuery
You might like
PHP人民币金额数字转中文大写的函数代码
2013/02/27 PHP
php+xml实现在线英文词典之添加词条的方法
2015/01/23 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
fckeditor上传文件按日期存放及重命名方法
2015/05/22 PHP
Google Suggest ;-) 基于js的动态下拉菜单
2006/10/11 Javascript
javascript实现的基于金山词霸网络翻译的代码
2010/01/15 Javascript
jquery访问ashx文件示例代码
2014/08/11 Javascript
js中获取 table节点各tr及td的内容简单实例
2016/10/14 Javascript
微信小程序实现表单校验功能
2020/03/30 Javascript
vue实现div拖拽互换位置
2020/07/29 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
快速了解Node中的Stream流是什么
2019/02/13 Javascript
vue指令之表单控件绑定v-model v-model与v-bind结合使用
2019/04/17 Javascript
Layui动态生成select下拉选择框不显示的解决方法
2019/09/24 Javascript
原生JS实现拖拽效果
2020/12/04 Javascript
[02:22]2018DOTA2亚洲邀请赛VG赛前采访
2018/04/03 DOTA
在Python中使用SQLite的简单教程
2015/04/29 Python
浅谈Python2.6和Python3.0中八进制数字表示的区别
2017/04/28 Python
Python3 适合初学者学习的银行账户登录系统实例
2017/08/08 Python
分享一下如何编写高效且优雅的 Python 代码
2017/09/07 Python
python实现石头剪刀布程序
2021/01/20 Python
Pandas的read_csv函数参数分析详解
2019/07/02 Python
Python 从subprocess运行的子进程中实时获取输出的例子
2019/08/14 Python
Python 实现毫秒级淘宝抢购脚本的示例代码
2019/09/16 Python
Python迷宫生成和迷宫破解算法实例
2019/12/24 Python
python程序需要编译吗
2020/06/19 Python
Python中如何定义一个函数
2016/09/06 面试题
信息工程学院毕业生推荐信
2013/11/05 职场文书
简单的辞职信范文
2014/01/18 职场文书
毕业生自荐书
2014/02/02 职场文书
应届生面试求职信
2014/07/02 职场文书
龙潭大峡谷导游词
2015/02/10 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
《水上飞机》教学反思
2016/02/20 职场文书
读《解忧杂货店》有感:请相信一切都是最好的安排
2019/11/07 职场文书
你离财务总监还有多远?速览CFO的岗位职责
2019/11/18 职场文书