详解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 相关文章推荐
类似GMAIL的Ajax信息反馈显示
Feb 16 Javascript
javascript实现des解密加密全过程
Apr 03 Javascript
jQuery中odd选择器的定义和用法
Dec 23 Javascript
js点击返回跳转到指定页面实现过程
Aug 20 Javascript
AngularJS基础 ng-focus 指令简单示例
Aug 01 Javascript
javaScript语法总结
Nov 25 Javascript
老生常谈的跨域处理
Jan 11 Javascript
DOM事件探秘篇
Feb 15 Javascript
小程序tab页无法传递参数的方法
Aug 03 Javascript
js实现转动骰子模型
Oct 24 Javascript
JS实现网页烟花动画效果
Mar 10 Javascript
利用uni-app生成微信小程序的踩坑记录
Apr 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网站被挂木马后的修复方法总结
2014/11/06 PHP
Thinkphp结合ajaxFileUpload实现异步图片传输示例
2017/03/13 PHP
laravel ORM关联关系中的 with和whereHas用法
2019/10/16 PHP
javascript 日历提醒系统( 兼容所有浏览器 )
2009/04/07 Javascript
js以对象为索引的关联数组
2010/07/04 Javascript
node.js中的dns.getServers方法使用说明
2014/12/08 Javascript
Windows下用PyCharm和Visual Studio开始Python编程
2015/10/26 Javascript
js纯数字逐一停止显示效果的实现代码
2016/03/16 Javascript
jQuery.form插件的使用及跨域异步上传文件
2016/04/27 Javascript
javaScript事件机制兼容【详细整理】
2016/07/23 Javascript
JavaScript数据结构之二叉树的计数算法示例
2017/04/13 Javascript
webpack配置的最佳实践分享
2017/04/21 Javascript
jquery实现提示语淡入效果
2017/05/05 jQuery
深入理解jquery的$.extend()、$.fn和$.fn.extend()
2017/07/08 jQuery
微信小程序日历/日期选择插件使用方法详解
2018/12/28 Javascript
js控制随机数生成概率代码实例
2019/03/21 Javascript
JavaScript实现答题评分功能页面
2020/06/24 Javascript
video.js添加自定义组件的方法
2020/12/09 Javascript
[01:38]DOTA2 2015国际邀请赛中国区预选赛 Showopen
2015/06/01 DOTA
Python可变参数用法实例分析
2017/04/02 Python
Python 批量合并多个txt文件的实例讲解
2018/05/08 Python
python调用百度REST API实现语音识别
2018/08/30 Python
python文件读取失败怎么处理
2020/06/23 Python
python归并排序算法过程实例讲解
2020/11/04 Python
香港唯港荟酒店预订:Hotel ICON
2018/03/27 全球购物
请解释流与文件有什么不同
2016/07/29 面试题
Python里面如何实现tuple和list的转换
2012/06/13 面试题
法人授权委托书
2014/04/03 职场文书
师范生自荐信模板
2014/05/28 职场文书
药店采购员岗位职责
2014/09/30 职场文书
民主生活会发言材料
2014/10/20 职场文书
基层党员学习党的群众路线教育实践活动心得体会
2014/11/04 职场文书
2014年大学团支部工作总结
2014/12/02 职场文书
材料员岗位职责
2015/02/10 职场文书
电脑开机弹出documents文件夹怎么回事?弹出documents文件夹解决方法
2022/04/08 数码科技
mysql sql常用语句大全
2022/06/21 MySQL