详解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 相关文章推荐
jqueyr判断checkbox组的选中(示例代码)
Nov 08 Javascript
javascript监听鼠标滚轮事件浅析
Jun 05 Javascript
JavaScript学习笔记之DOM基础 2.4
Aug 14 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
Sep 02 Javascript
JavaScript判断按钮被点击的方法
Dec 13 Javascript
基于jquery实现图片相关操作(重绘、获取尺寸、调整大小、缩放)
Dec 25 Javascript
jQuery简单验证上传文件大小及类型的方法
Jun 02 Javascript
Javascript中的数组常用方法解析
Jun 17 Javascript
JavaScript中运算符规则和隐式类型转换示例详解
Sep 06 Javascript
浅谈Vue.js组件(二)
Apr 09 Javascript
js实现百度淘宝搜索功能
Feb 17 Javascript
JavaScript 空间坐标的使用
Aug 19 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导出Word文档的原理和实例
2013/10/21 PHP
使用Yii2实现主从数据库设置
2016/11/20 PHP
laravel学习笔记之模型事件的几种用法示例
2017/08/15 PHP
window.location.hash 属性使用说明
2010/03/20 Javascript
JavaScript的parseInt 取整使用
2011/05/09 Javascript
利用js实现禁止复制文本信息
2015/06/03 Javascript
JS实现一个简单的日历
2017/02/22 Javascript
Angular4 反向代理Details实践
2018/05/30 Javascript
对VUE中的对象添加属性
2018/09/18 Javascript
vue2中引用及使用 better-scroll的方法详解
2018/11/15 Javascript
JavaScript中的一些实用小技巧总结
2019/04/07 Javascript
关于vue-cli 3配置打包优化要点(推荐)
2019/04/22 Javascript
微信小程序实现时间进度条功能
2020/11/17 Javascript
jQuery实现简易聊天框
2020/02/08 jQuery
详解Vue.js 可拖放文本框组件的使用
2021/03/03 Vue.js
python中input()与raw_input()的区别分析
2016/02/27 Python
python2 与python3的print区别小结
2018/01/16 Python
django自带调试服务器的使用详解
2019/08/29 Python
python随机生成库faker库api实例详解
2019/11/28 Python
在服务器上安装python3.8.2环境的教程详解
2020/04/26 Python
详解python中groupby函数通俗易懂
2020/05/14 Python
Softmax函数原理及Python实现过程解析
2020/05/22 Python
Python文件操作及内置函数flush原理解析
2020/10/13 Python
matplotlib绘制正余弦曲线图的实现
2021/02/22 Python
纯CSS实现预加载动画效果
2017/09/06 HTML / CSS
伦敦哈德森鞋:Hudson Shoes
2018/02/06 全球购物
法国在线宠物店:zooplus.fr
2018/02/23 全球购物
中学生学习生活的自我评价
2013/10/26 职场文书
升国旗仪式主持词
2014/03/19 职场文书
教师新年寄语
2014/04/03 职场文书
机械工程及自动化专业求职信
2014/09/03 职场文书
数学考试作弊检讨书300字
2015/02/16 职场文书
《作风建设永远在路上》心得体会
2016/01/21 职场文书
python正则表达式re.search()的基本使用教程
2021/05/21 Python
写好Python代码的几条重要技巧
2021/05/21 Python
MySQL分区路径子分区再分区
2022/04/13 MySQL