详解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 相关文章推荐
Javascript & DHTML 实例编程(教程)(三)初级实例篇1—上传文件控件实例
Jun 02 Javascript
jquery ui resizable bug解决方法
Oct 26 Javascript
window resize和scroll事件的基本优化思路
Apr 29 Javascript
JavaScript中实现无缝滚动、分享到侧边栏实例代码
Apr 06 Javascript
js运动事件函数详解
Oct 21 Javascript
微信公众平台开发教程(五)详解自定义菜单
Dec 02 Javascript
小程序封装wx.request请求并创建接口管理文件的实现
Apr 29 Javascript
Vue中UI组件库之Vuex与虚拟服务器初识
May 07 Javascript
快速搭建Node.js(Express)用户注册、登录以及授权的方法
May 09 Javascript
加速vue组件渲染之性能优化
Apr 09 Javascript
vue中v-for循环选中点击的元素并对该元素添加样式操作
Jul 17 Javascript
详细介绍Next.js脚手架完整搭建封装
Apr 26 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
DedeCms模板安装/制作概述
2007/03/11 PHP
PHP使用mysqli操作MySQL数据库的简单方法
2017/02/04 PHP
JavaScript随机排序(随即出牌)
2010/09/17 Javascript
jQuery 回调函数(callback)的使用和基础
2015/02/26 Javascript
jQuery的animate函数实现图文切换动画效果
2015/05/03 Javascript
在JavaScript中操作时间之getUTCDate()方法的使用
2015/06/10 Javascript
javascript 使用for循环时该注意的问题-附问题总结
2015/08/19 Javascript
jquery实现的点击翻书效果代码
2015/11/04 Javascript
jQuery实现图片文字淡入淡出效果
2015/12/21 Javascript
Jquery和angularjs获取check框选中的值的方法汇总
2016/01/17 Javascript
jquery插件格式实例分析
2016/06/16 Javascript
jQuery实现点击弹出背景变暗遮罩效果实例代码
2016/06/24 Javascript
EasyUI折叠表格层次显示detailview详解及实例
2016/12/28 Javascript
利用Javascript实现一套自定义事件机制
2017/12/14 Javascript
webpack源码之loader机制详解
2018/04/06 Javascript
基于JavaScript 实现拖放功能
2019/09/12 Javascript
JS数组方法reverse()用法实例分析
2020/01/18 Javascript
通过vue刷新左侧菜单栏操作
2020/08/06 Javascript
详解Vue2的diff算法
2021/01/06 Vue.js
[53:52]EG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
pycharm 使用心得(三)Hello world!
2014/06/05 Python
Python实现线程状态监测简单示例
2018/03/28 Python
python安装pywin32clipboard的操作方法
2019/01/24 Python
python爬取基于m3u8协议的ts文件并合并
2019/04/26 Python
python正则爬取某段子网站前20页段子(request库)过程解析
2019/08/10 Python
python 项目目录结构设置
2020/02/14 Python
pytorch 实现在一个优化器中设置多个网络参数的例子
2020/02/20 Python
Django项目uwsgi+Nginx保姆级部署教程实现
2020/04/19 Python
如何教少儿学习Python编程
2020/07/10 Python
python开发一款翻译工具
2020/10/10 Python
HTML5教程之html 5 本地数据库(Web Sql Database)
2014/04/03 HTML / CSS
html2canvas截图空白问题的解决
2020/03/24 HTML / CSS
美国最便宜的旅游网站:CheapTickets
2017/07/09 全球购物
银行竞聘演讲稿
2014/05/16 职场文书
根叔历年演讲稿
2014/05/20 职场文书
2015年医药代表工作总结
2015/04/25 职场文书