详解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 相关文章推荐
11款基于Javascript的文件管理器
Oct 25 Javascript
为JavaScript类型增加方法的实现代码(增加功能)
Dec 29 Javascript
JavaScript实现网页图片等比例缩放实现代码及调用方式
Feb 25 Javascript
鼠标滚轮控制网页横向移动实现思路
Mar 22 Javascript
如何用JavaScript动态呼叫函数(两种方式)
May 03 Javascript
javascript中expression的用法整理
May 13 Javascript
利用jquery获取select下拉框的值
Nov 23 Javascript
微信小程序 form组件详解及简单实例
Jan 10 Javascript
vue采用EventBus实现跨组件通信及注意事项小结
Jun 14 Javascript
Vue项目引发的「过滤器」使用教程
Mar 12 Javascript
微信小程序前端自定义分享的实现方法
Jun 13 Javascript
jQuery实现B2B网站后台管理系统侧导航
Jul 08 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
PHP删除HTMl标签的三种解决方法
2013/06/30 PHP
PHP错误Allowed memory size of 67108864 bytes exhausted的3种解决办法
2014/07/28 PHP
PHP实现十进制、二进制、八进制和十六进制转换相关函数用法分析
2017/04/25 PHP
Yii框架的redis命令使用方法简单示例
2019/10/15 PHP
激活 ActiveX 控件
2006/10/09 Javascript
js Dialog 实践分享
2012/10/22 Javascript
js实现单一html页面两套css切换代码
2013/04/11 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
JS使用parseInt解析数字实现求和的方法
2015/08/05 Javascript
JavaScript实现点击单元格改变背景色的方法
2016/02/12 Javascript
jQuery实现发送验证码并60秒倒计时功能
2016/11/25 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
2017/02/16 Javascript
浅谈React Native Flexbox布局(小结)
2018/01/08 Javascript
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
2018/04/20 Javascript
关于js的三种使用方式(行内js、内部js、外部js)的程序代码
2018/05/05 Javascript
AngularJS标签页tab选项卡切换功能经典实例详解
2018/05/16 Javascript
Javascript 关于基本类型和引用类型的个人理解
2019/11/01 Javascript
优化Vue中date format的性能详解
2020/01/13 Javascript
ES6新增的数组知识实例小结
2020/05/23 Javascript
vue中destroyed方法的使用说明
2020/07/21 Javascript
Openlayers实现地图的基本操作
2020/09/28 Javascript
[51:44]2018DOTA2亚洲邀请赛 4.3 突围赛 Optic vs iG 第二场
2018/04/04 DOTA
python3序列化与反序列化用法实例
2015/05/26 Python
Python字符串格式化
2015/06/15 Python
举例区分Python中的浅复制与深复制
2015/07/02 Python
python结合selenium获取XX省交通违章数据的实现思路及代码
2016/06/26 Python
shelve  用来持久化任意的Python对象实例代码
2016/10/12 Python
Python实现基本数据结构中栈的操作示例
2017/12/04 Python
Tensorflow累加的实现案例
2020/02/05 Python
基于python生成英文版词云图代码实例
2020/05/16 Python
男女时尚与复古风格在线购物:RoseGal(全球免费送货)
2017/07/19 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
日语系毕业生推荐信
2013/11/11 职场文书
一份创业计划书范文
2014/02/08 职场文书
2015年秋学期教研工作总结
2015/10/14 职场文书
MySQL如何解决幻读问题
2021/08/07 MySQL