详解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中对节点进行操作的相关介绍
Apr 16 Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
Oct 22 Javascript
javascript实现网站加入收藏功能
Dec 16 Javascript
js判断数组key是否存在(不用循环)的简单实例
Aug 03 Javascript
Javascript下拉刷新的简单实现
Feb 14 Javascript
js截取字符串功能的实现方法
Sep 27 Javascript
react 创建单例组件的方法
Apr 26 Javascript
vue组件实现进度条效果
Jun 06 Javascript
JS内置对象和Math对象知识点详解
Apr 03 Javascript
JS使用Chrome浏览器实现调试线上代码
Jul 23 Javascript
微信小程序实现翻牌抽奖动画
Sep 21 Javascript
vue+iview使用树形控件的具体使用
Nov 02 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中使用imagick实现把PDF转成图片
2015/01/26 PHP
php运行报错Call to undefined function curl_init()的最新解决方法
2016/11/20 PHP
PHP实现的基于单向链表解决约瑟夫环问题示例
2017/09/30 PHP
用javascript实现无刷新更新数据的详细步骤 asp
2006/12/26 Javascript
js滚动条多种样式,推荐
2007/02/05 Javascript
JS 创建对象(常见的几种方法)
2008/11/03 Javascript
javascript 多浏览器 事件大全
2010/03/23 Javascript
javascript与webservice的通信实现代码
2010/12/25 Javascript
JS OffsetParent属性深入解析
2014/01/13 Javascript
利用vue写todolist单页应用
2016/12/15 Javascript
JavaScript中数组Array方法详解
2017/02/27 Javascript
Bootstrap实现的经典栅格布局效果实例【附demo源码】
2017/03/30 Javascript
Vue组件tree实现树形菜单
2017/04/13 Javascript
详解Nodejs 通过 fs.createWriteStream 保存文件
2017/10/10 NodeJs
vue实现简单瀑布流布局
2020/05/28 Javascript
详解Vue 的异常处理机制
2020/11/30 Vue.js
[03:22]DSPL第一期精彩集锦:酷炫到底!
2014/11/07 DOTA
[00:09]DOTA2全国高校联赛 精彩活动引爆全场
2018/05/30 DOTA
Python实现求最大公约数及判断素数的方法
2015/05/26 Python
Python使用bs4获取58同城城市分类的方法
2015/07/08 Python
Go/Python/Erlang编程语言对比分析及示例代码
2018/04/23 Python
pandas 读取各种格式文件的方法
2018/06/22 Python
Python3 使用cookiejar管理cookie的方法
2018/12/28 Python
django使用xadmin的全局配置详解
2019/11/15 Python
wxpython自定义下拉列表框过程图解
2020/02/14 Python
Python DES加密实现原理及实例解析
2020/07/17 Python
中国最大的名表商城:万表网
2016/08/29 全球购物
WiFi云数码相框:Nixplay
2018/07/05 全球购物
Visual-Click葡萄牙:欧洲领先的在线眼镜商
2020/02/17 全球购物
有机婴儿毛毯和衣服:Monica + Andy
2020/03/01 全球购物
科研先进个人典型材料
2014/01/31 职场文书
财政专业求职信范文
2014/02/19 职场文书
金融事务专业毕业生求职信
2014/02/23 职场文书
小学生操行评语大全
2014/04/22 职场文书
2014年小学辅导员工作总结
2014/12/23 职场文书
2015年科研工作总结范文
2015/05/13 职场文书