详解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 点击按钮显示和隐藏层的代码
Jul 25 Javascript
通过一段代码简单说js中的this的使用
Jul 23 Javascript
利用JS判断用户是否上网(连接网络)
Dec 23 Javascript
基于jquery实现导航菜单高亮显示(两种方法)
Aug 23 Javascript
JS+CSS实现简单滑动门(滑动菜单)效果
Sep 19 Javascript
详解JavaScript基于面向对象之创建对象(1)
Dec 10 Javascript
javascript html5移动端轻松实现文件上传
Mar 27 Javascript
Bootstrap实现各种进度条样式详解
Apr 13 Javascript
angular 实时监听input框value值的变化触发函数方法
Aug 31 Javascript
vue完成项目后,打包成静态文件的方法
Sep 03 Javascript
JS中作用域以及变量范围分析
Jul 18 Javascript
ajax jquery实现页面某一个div的刷新效果
Mar 04 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
松下Panasonic RF-B65电路分析
2021/03/02 无线电
PHP中的float类型使用说明
2010/07/27 PHP
php线性表顺序存储实现代码(增删查改)
2012/02/16 PHP
php验证码的制作思路和实现方法
2015/11/12 PHP
自动更新作用
2006/10/08 Javascript
javascript中强制执行toString()具体实现
2013/04/27 Javascript
Javascript弹出窗口的各种方法总结
2013/11/11 Javascript
Node.js实现Excel转JSON
2015/04/24 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
2016/05/28 Javascript
Javascript之Math对象详解
2016/06/07 Javascript
微信小程序-小说阅读小程序实例(demo)
2017/01/12 Javascript
js通过Date对象实现倒计时动画效果
2017/10/27 Javascript
JS从非数组对象转数组的方法小结
2018/03/26 Javascript
JS实现字符串去重及数组去重的方法示例
2018/04/21 Javascript
Bootstrap Table实现定时刷新数据的方法
2018/08/13 Javascript
微信小程序自定义toast组件的方法详解【含动画】
2019/05/11 Javascript
微信小程序之侧边栏滑动实现过程解析(附完整源码)
2019/08/23 Javascript
vue实现图片裁剪后上传
2020/12/16 Vue.js
[03:28]2014DOTA2国际邀请赛 走近EG战队天才中单Arteezy
2014/07/12 DOTA
[03:37]2016完美“圣”典 风云人物:Mikasa专访
2016/12/07 DOTA
[01:03]悬念揭晓 11月26日DOTA2完美盛典不见不散
2017/11/23 DOTA
Python  __getattr__与__setattr__使用方法
2008/09/06 Python
Request的中断和ErrorHandler实例解析
2018/02/12 Python
python爬取网页内容转换为PDF文件
2020/07/28 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
Python3中lambda表达式与函数式编程讲解
2019/01/14 Python
python web框架中实现原生分页
2019/09/08 Python
PyTorch 对应点相乘、矩阵相乘实例
2019/12/27 Python
pytorch模型存储的2种实现方法
2020/02/14 Python
Ted Baker美国官网:英国时尚品牌
2018/10/29 全球购物
新手上路标语
2014/06/20 职场文书
中职招生先进个人材料
2014/08/31 职场文书
群众路线自我剖析材料
2014/10/08 职场文书
Python 快速验证代理IP是否有效的方法实现
2021/07/15 Python
浅谈MySQL之select优化方案
2021/08/07 MySQL
springcloud整合seata
2022/05/20 Java/Android