详解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 相关文章推荐
点图片上一页下一页翻页效果
Jul 09 Javascript
ajaxControlToolkit AutoCompleteExtender的用法
Oct 30 Javascript
js中parseInt函数浅谈
Jul 31 Javascript
Javascript中的getUTCHours()方法使用详解
Jun 10 Javascript
javascript实现列表滚动的方法
Jul 30 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
Dec 24 Javascript
用jmSlip编写移动端顶部日历选择控件
Oct 24 Javascript
基于ES6作用域和解构赋值详解
Nov 03 Javascript
玩转Koa之核心原理分析
Dec 29 Javascript
微信小程序实现动态列表项的顺序加载动画
Jul 25 Javascript
基于openlayers实现角度测量功能
Sep 28 Javascript
输入框跟随文字内容适配宽实现示例
Aug 14 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/10/09 PHP
php 生成文字png图片的代码
2011/04/17 PHP
Symfony2安装的方法(2种方法)
2016/02/04 PHP
完美解决phpexcel导出到xls文件出现乱码的问题
2016/10/29 PHP
Laravel框架文件上传功能实现方法示例
2019/04/16 PHP
JavaScript 设计模式学习 Factory
2009/07/29 Javascript
jquery获得下拉框值的代码
2011/08/13 Javascript
防止jQuery ajax Load使用缓存的方法小结
2014/02/22 Javascript
JQuery基础语法小结
2015/02/27 Javascript
jquery简单倒计时实现方法
2015/12/18 Javascript
浅析Javascript中bind()方法的使用与实现
2016/05/30 Javascript
Jquery和BigFileUpload实现大文件上传及进度条显示
2016/06/27 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
2016/09/04 Javascript
jQuery实现的简单无刷新评论功能示例
2017/11/08 jQuery
Vue 监听列表item渲染事件方法
2018/09/06 Javascript
JS中验证整数和小数的正则表达式
2018/10/08 Javascript
使用vue实现HTML页面生成图片的方法
2020/03/12 Javascript
如何在 Vue 表单中处理图片
2021/01/26 Vue.js
python实现排序算法
2014/02/14 Python
简单介绍Python中的decode()方法的使用
2015/05/18 Python
Python中数字以及算数运算符的相关使用
2015/10/12 Python
使用python在本地电脑上快速处理数据
2017/06/22 Python
python通过ffmgep从视频中抽帧的方法
2018/12/05 Python
python遍历小写英文字母的方法
2019/01/02 Python
python给微信好友定时推送消息的示例
2019/02/20 Python
对python 中class与变量的使用方法详解
2019/06/26 Python
用python建立两个Y轴的XY曲线图方法
2019/07/08 Python
django认证系统实现自定义权限管理的方法
2019/08/28 Python
Python获取、格式化当前时间日期的方法
2020/02/10 Python
浅谈Python __init__.py的作用
2020/10/28 Python
非常漂亮的CSS3百叶窗焦点图动画
2016/02/24 HTML / CSS
优秀教导主任事迹材料
2014/05/09 职场文书
勤奋学习演讲稿
2014/05/10 职场文书
体育教师求职信
2014/06/30 职场文书
python爬虫之selenium库的安装及使用教程
2021/05/23 Python
springboot新建项目pom.xml文件第一行报错的解决
2022/01/18 Java/Android