详解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 仿QQ校友的DIV模拟窗口效果源码
Mar 24 Javascript
基于jquery的从一个页面跳转到另一个页面的指定位置的实现代码(带平滑移动的效果)
May 24 Javascript
eclipse如何忽略js文件报错(附图)
Oct 30 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
Feb 13 Javascript
javascript实现日期时间动态显示示例代码
Sep 08 Javascript
JS实现仿QQ效果的三级竖向菜单
Sep 25 Javascript
详解javascript中对数据格式化的思考
Jan 23 Javascript
微信小程序使用wxParse解析html的方法教程
Jul 06 Javascript
小程序自定义组件实现城市选择功能
Jul 18 Javascript
详解vue-cli官方脚手架配置
Jul 20 Javascript
JavaScript中import用法总结
Jan 20 Javascript
小程序组件之自定义顶部导航实例
Jun 12 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的session cookie错误
2009/08/09 PHP
php中使用Akismet防止垃圾评论的代码
2011/06/10 PHP
Yii框架引入coreseek分页功能示例
2019/02/08 PHP
JS实现self的resend
2010/07/22 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
JS 实现导航栏悬停效果
2013/09/23 Javascript
Vue.js实现无限加载与分页功能开发
2016/11/03 Javascript
bootstrap模态框关闭后清除模态框的数据方法
2018/08/10 Javascript
详解Angular中实现自定义组件的双向绑定的两种方法
2018/11/23 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
layui(1.0.9)文件上传upload,前后端的实例代码
2019/09/26 Javascript
JS实现排行榜文字向上滚动轮播效果
2019/11/26 Javascript
node使用request请求的方法
2019/12/20 Javascript
Vue实现Header渐隐渐现效果的实例代码
2020/11/05 Javascript
JS如何监听div的resize事件详解
2020/12/03 Javascript
[02:36]DOTA2混沌骑士 英雄基础教程
2013/11/26 DOTA
[57:29]Alliance vs KG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/17 DOTA
Python脚本实现集群检测和管理功能
2015/03/06 Python
利用Python中SocketServer 实现客户端与服务器间非阻塞通信
2016/12/15 Python
Python实现PS滤镜碎片特效功能示例
2018/01/24 Python
Python实现决策树C4.5算法的示例
2018/05/30 Python
python实现动态数组的示例代码
2019/07/15 Python
Python 调用 Windows API COM 新法
2019/08/22 Python
python、Matlab求定积分的实现
2019/11/20 Python
计算Python Numpy向量之间的欧氏距离实例
2020/05/22 Python
css3 flex实现div内容水平垂直居中的几种方法
2020/03/27 HTML / CSS
《桃花心木》教学反思
2014/02/17 职场文书
校企合作协议书
2014/04/16 职场文书
学校爱国卫生月活动总结
2014/06/25 职场文书
小学生读书活动总结
2014/06/30 职场文书
委托培训协议书
2014/11/17 职场文书
社区五一劳动节活动总结
2015/02/09 职场文书
2015年店长个人工作总结
2015/10/23 职场文书
又涨知识了,自律到底多重要?
2019/06/27 职场文书
nginx作grpc的反向代理踩坑总结
2021/07/07 Servers
MySQL 条件查询的常用操作
2022/04/28 MySQL