详解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性能最佳实践的讨论,与求教
Mar 30 Javascript
jQuery(非HTML5)可编辑表格实现代码
Dec 11 Javascript
JSONP获取Twitter和Facebook文章数的具体步骤
Feb 24 Javascript
jquery判断输入密码两次是否相等
Apr 22 Javascript
微信小程序实现图片轮播及文件上传
Apr 07 Javascript
js封装成插件的步骤方法
Sep 11 Javascript
Vue Router的懒加载路径的解决方法
Jun 21 Javascript
vue中动态添加class类名的方法
Sep 05 Javascript
详解easyui 切换主题皮肤
Apr 04 Javascript
Vue+Koa2 打包后进行线上部署的教程详解
Jul 31 Javascript
Vue项目实现换肤功能的一种方案分析
Aug 28 Javascript
vue实现给div绑定keyup的enter事件
Jul 31 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
自己做矿石收音机
2021/03/02 无线电
关于Appserv无法打开localhost问题的解决方法
2009/10/16 PHP
php eval函数用法 PHP中eval()函数小技巧
2012/10/31 PHP
基于php常用正则表达式的整理汇总
2013/06/08 PHP
配置php.ini实现PHP文件上传功能
2014/11/27 PHP
PHP简单实现模拟登陆功能示例
2017/09/15 PHP
php实现的中秋博饼游戏之绘制骰子图案功能示例
2017/11/06 PHP
PHP实现的字符串匹配算法示例【sunday算法】
2017/12/19 PHP
尝试在让script的type属性等于text/html
2013/01/15 Javascript
url参数中有+、空格、=、%、&、#等特殊符号的问题解决
2013/05/15 Javascript
window.open打开页面居中显示的示例代码
2013/12/27 Javascript
jq实现酷炫的鼠标经过图片翻滚效果
2014/03/12 Javascript
javascript和jquery实现设置和移除文本框默认值效果代码
2015/01/13 Javascript
Javascript中的包装类型介绍
2015/04/02 Javascript
jquery带翻页动画的电子杂志代码分享
2015/08/21 Javascript
jquery自定义右键菜单、全选、不连续选择
2016/03/01 Javascript
Extjs实现下拉菜单效果
2016/04/01 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
超实用的javascript时间处理总结
2016/08/16 Javascript
MvcPager分页控件 适用于Bootstrap
2017/06/03 Javascript
react-redux中connect的装饰器用法@connect详解
2018/01/13 Javascript
vue中使用better-scroll实现滑动效果及注意事项
2018/11/15 Javascript
Python3 入门教程 简单但比较不错
2009/11/29 Python
Python使用回溯法子集树模板解决爬楼梯问题示例
2017/09/08 Python
PyQt打开保存对话框的方法和使用详解
2019/02/27 Python
Python操作MySQL数据库的两种方式实例分析【pymysql和pandas】
2019/03/18 Python
新手入门Python编程的8个实用建议
2019/07/12 Python
Python中关于浮点数的冷知识
2019/09/22 Python
opencv 查找连通区域 最大面积实例
2020/06/04 Python
Python xlrd模块导入过程及常用操作
2020/06/10 Python
Original Penguin美国官网:布拉德皮特、强尼德普喜爱的服装品牌
2016/10/25 全球购物
英语专业毕业生自荐信范文
2013/12/31 职场文书
工作求职自荐信
2014/06/13 职场文书
报到证办理个人委托书
2014/10/06 职场文书
2015年个人思想总结
2015/03/09 职场文书
放飞理想主题班会
2015/08/14 职场文书