详解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 相关文章推荐
[HTML/CSS/Javascript]WWTJS
Sep 25 Javascript
IE浏览器兼容Firefox的JS脚本的代码
Oct 23 Javascript
Extjs EditorGridPanel中ComboBox列的显示问题
Jul 04 Javascript
jQuery客户端分页实例代码
Nov 18 Javascript
jquery html动态生成select标签出问题的解决方法
Nov 20 Javascript
深入理解JavaScript系列(30):设计模式之外观模式详解
Mar 03 Javascript
JS制作类似选项卡切换的年历
Dec 03 Javascript
jQuery插件MovingBoxes实现左右滑动中间放大图片效果
Feb 28 Javascript
用户管理的设计_jquery的ajax实现二级联动效果
Jul 13 jQuery
vue.js实现简单轮播图效果
Oct 10 Javascript
jQuery zTree 异步加载添加子节点重复问题
Nov 29 jQuery
vue.js 使用axios实现下载功能的示例
Mar 05 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代码(星期六,星期日总和)
2009/11/12 PHP
PHP swfupload图片上传的实例代码
2013/09/30 PHP
php判断电脑访问、手机访问的例子
2014/05/10 PHP
PHP设计模式之组合模式定义与应用示例
2020/02/01 PHP
详解PHP中的8个魔术常量
2020/07/06 PHP
使用prototype.js进行异步操作
2007/02/07 Javascript
JS操作图片(增,删,改) 例子
2013/04/17 Javascript
jQuery实现单行文字间歇向上滚动源代码
2013/06/02 Javascript
Js(JavaScript)中,弹出是或否的选择框示例(confirm用法的实例分析)
2013/07/09 Javascript
JS验证身份证有效性示例
2013/10/11 Javascript
Javascript变量作用域详解
2013/12/06 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
JS仿Windows开机启动Loading进度条的方法
2015/02/26 Javascript
jQuery实现菜单式图片滑动切换
2015/03/14 Javascript
javascript日期操作详解(脚本之家整理)
2015/09/05 Javascript
每天一篇javascript学习小结(RegExp对象)
2015/11/17 Javascript
基于Bootstrap分页的实例讲解(必看篇)
2017/07/04 Javascript
浅谈webpack下的AOP式无侵入注入
2017/11/12 Javascript
js canvas实现画图、滤镜效果
2018/11/27 Javascript
JS实现点击按钮随机生成可拖动的不同颜色块示例
2019/01/30 Javascript
node后端服务保活的实现
2019/11/10 Javascript
[01:00:11]DOTA2-DPC中国联赛 正赛 CDEC vs DLG BO3 第一场 2月7日
2021/03/11 DOTA
教你使用python画一朵花送女朋友
2018/03/29 Python
Python实现监控键盘鼠标操作示例【基于pyHook与pythoncom模块】
2018/09/04 Python
Django 静态文件配置过程详解
2019/07/23 Python
python3.6 tkinter实现屏保小程序
2019/07/30 Python
python使用 __init__初始化操作简单示例
2019/09/26 Python
世界上最大的高分辨率在线图片库:Alamy
2018/07/07 全球购物
幼儿园小班教学反思
2014/02/02 职场文书
《愚公移山》教学反思
2014/02/20 职场文书
竞选班长自荐书范文
2014/03/09 职场文书
2014年质量工作总结
2014/11/22 职场文书
2014年残疾人工作总结
2014/12/06 职场文书
《珍珠鸟》教学反思
2016/02/16 职场文书
2016年第二十届“母亲节暨幸福工程救助贫困母亲活动日”活动总结
2016/04/06 职场文书
退休劳动合同怎么写?
2019/10/25 职场文书