详解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 相关文章推荐
兼容Mozilla必须知道的知识。
Jan 09 Javascript
setTimeout和setInterval的浏览器兼容性分析
Feb 27 Javascript
Javascript类定义语法,私有成员、受保护成员、静态成员等介绍
Dec 08 Javascript
jquery仿QQ商城带左右按钮控制焦点图片切换滚动效果
Jun 27 Javascript
JavaScript知识点总结(四)之逻辑OR运算符详解
May 31 Javascript
js表单登陆验证示例
Oct 19 Javascript
JS实现复制内容到剪贴板功能
Feb 05 Javascript
基于Vue2.X的路由和钩子函数详解
Feb 09 Javascript
JS返回页面时自动回滚到历史浏览位置
Sep 26 Javascript
vue elementUI table 自定义表头和行合并的实例代码
May 22 Javascript
JS实现返回上一页并刷新页面的方法分析
Jul 16 Javascript
小程序采集录音并上传到后台
Nov 22 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基础知识:函数基础知识
2006/12/13 PHP
PHP远程连接MYSQL数据库非常慢的解决方法
2008/07/05 PHP
一个php短网址的生成代码(仿微博短网址)
2014/05/07 PHP
PHP+FFMPEG实现将视频自动转码成H264标准Mp4文件
2014/09/24 PHP
php检查页面是否被百度收录
2015/10/28 PHP
LazyLoad 延迟加载(按需加载)
2010/05/31 Javascript
jQuery获取浏览器中的分辨率实现代码
2013/04/23 Javascript
JS+CSS相对定位实现的下拉菜单
2015/10/06 Javascript
jQuery+PHP实现微信转盘抽奖功能的方法
2016/05/25 Javascript
jQuery实现的简单百分比进度条效果示例
2016/08/01 Javascript
JavaScript实现水平进度条拖拽效果
2017/01/18 Javascript
JavaScript无阻塞加载和defer、async详解
2017/02/26 Javascript
Node.js中多进程模块Cluster的介绍与使用
2017/05/27 Javascript
将 vue 生成的 js 上传到七牛的实例
2017/07/28 Javascript
nodejs 如何手动实现服务器
2018/08/20 NodeJs
Webpack4 使用Babel处理ES6语法的方法示例
2019/03/07 Javascript
vue实现倒计时获取验证码效果
2020/04/17 Javascript
JS实现关闭小广告特效
2021/01/29 Javascript
三步搞定:Vue.js调用Android原生操作
2020/09/07 Javascript
vue项目中播放rtmp视频文件流的方法
2020/09/17 Javascript
在Python中使用poplib模块收取邮件的教程
2015/04/29 Python
python fabric实现远程部署
2017/01/05 Python
python中计算一个列表中连续相同的元素个数方法
2018/06/29 Python
Python global全局变量函数详解
2018/09/18 Python
Django 路由系统URLconf的使用
2018/10/11 Python
弄懂这56个Python使用技巧(轻松掌握Python高效开发)
2019/09/18 Python
pytorch 获取tensor维度信息示例
2020/01/03 Python
澳洲网红粉泥面膜:Sand & Sky
2019/08/13 全球购物
opencv实现图像几何变换
2021/03/24 Python
《我不是最弱小的》教学反思
2014/02/23 职场文书
2015员工年度考核评语
2015/03/25 职场文书
2015年宣传部工作总结范文
2015/03/31 职场文书
导游词之河北白洋淀
2020/01/15 职场文书
mysql死锁和分库分表问题详解
2021/04/16 MySQL
golang 实现并发求和
2021/05/08 Golang
索尼ICF-5900W收音机测评
2022/04/24 无线电