详解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 相关文章推荐
JQuery 确定css方框模型(盒模型Box Model)
Jan 22 Javascript
jQuery的观察者模式详解
Dec 22 Javascript
jQuery实现友好的轮播图片特效
Jan 12 Javascript
使用JavaScript脚本无法直接改变Asp.net中Checkbox控件的Enable属性的解决方法
Sep 16 Javascript
js实现页面跳转的几种方法小结
May 16 Javascript
js实现楼层效果的简单实例
Jul 15 Javascript
彻底理解js面向对象之继承
Feb 04 Javascript
JavaScript中发出HTTP请求最常用的方法
Jul 12 Javascript
基于Vue 2.0 监听文本框内容变化及ref的使用说明介绍
Aug 24 Javascript
解决echarts数据二次渲染不成功的问题
Jul 20 Javascript
vue+vuex+axios从后台获取数据存入vuex,组件之间共享数据操作
Jul 31 Javascript
JS+JQuery实现无缝连接轮播图
Dec 30 jQuery
如何在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
global.php
2006/12/09 PHP
使用PHP数组实现无限分类,不使用数据库,不使用递归.
2006/12/09 PHP
php中的实现trim函数代码
2007/03/19 PHP
php上的memcache和memcached两个pecl库
2010/03/29 PHP
浅析php变量修饰符static的使用
2013/06/28 PHP
PHP面向对象程序设计之接口用法
2014/08/20 PHP
php准确获取文件MIME类型的方法
2015/06/17 PHP
浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
2015/10/26 PHP
对比分析php中Cookie与Session的异同
2016/02/19 PHP
yii框架无限极分类的实现方法
2017/04/08 PHP
由JavaScript技术实现的web小游戏(不含网游)
2010/06/12 Javascript
用JQuery实现表格隔行变色和突出显示当前行的代码
2012/02/10 Javascript
javascript 基础篇4 window对象,DOM
2012/03/14 Javascript
jquery中使用$(#form).submit()重写提交表单无效原因分析及解决
2013/03/25 Javascript
Bootstrap中定制LESS-颜色及导航条(推荐)
2016/11/21 Javascript
JavaScript数组_动力节点Java学院整理
2017/06/26 Javascript
微信小程序 rich-text的使用方法
2017/08/04 Javascript
基于JavaScript实现幸运抽奖页面
2020/07/05 Javascript
node和vue实现商城用户地址模块
2018/12/05 Javascript
ES6箭头函数和扩展实例分析
2020/05/23 Javascript
centos下更新Python版本的步骤
2013/02/12 Python
用python代码做configure文件
2014/07/20 Python
使用python实现正则匹配检索远端FTP目录下的文件
2015/03/25 Python
python skimage 连通性区域检测方法
2018/06/21 Python
python3实现zabbix告警推送钉钉的示例
2019/02/20 Python
python3跳出一个循环的实例操作
2020/08/18 Python
有关HTML5中背景音乐的自动播放功能
2017/10/16 HTML / CSS
下面关于"联合"的题目的输出是什么
2013/08/06 面试题
计算机网络专业推荐信
2013/11/24 职场文书
副总经理岗位职责
2014/03/16 职场文书
党的群众路线教育实践活动个人对照检查材料(四风)
2014/11/05 职场文书
丧事酒宴答谢词
2015/09/30 职场文书
教师个人工作总结范文2015
2015/10/14 职场文书
七年级作文之英语老师
2019/10/28 职场文书
一篇文章带你了解Python和Java的正则表达式对比
2021/09/15 Python
python调用ffmpeg命令行工具便捷操作视频示例实现过程
2021/11/01 Python