利用require.js与angular搭建spa应用的方法实例


Posted in Javascript onJuly 19, 2017

前言

AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。AngularJS有着诸多特性,最为核心的是:MVVM、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。

本文是接上篇,angular 实战部分,angular比较适合spa项目,这里不借助任何seed和构建工具,直接从零搭建,基本的angular项目结构大致包含如下几个部分:

1)app.js 入口

2)index.html html框架页

3)lib(vendor)第三方类库

4)components 业务组件

5)styles/images 静态资源部分

1、常规实现

创建文件夹demo1,按照上述结构分别创建app.js ,index.html文件,创建lib、components、styles和images文件夹,最终如下图所示:

利用require.js与angular搭建spa应用的方法实例

在此基础上,我们增加三个业务组件home,about,contact,并初始化基本代码如下:

利用require.js与angular搭建spa应用的方法实例

核心代码文件

index.html

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>demo1</title>
 <script src="https://cdn.bootcss.com/angular.js/1.6.0/angular.js"></script>
 <script src="https://cdn.bootcss.com/angular-ui-router/1.0.3/angular-ui-router.js"></script>

 <script src='./app.js'></script>
 <script src='./components/home/home.controller.js'></script>
 <script src='./components/about/about.controller.js'></script>
 <script src='./components/contact/contact.controller.js'></script>

</head>
<body>
 <div class="nav">
 <ul>
  <li><a ui-sref="home">Home</a></li>
  <li><a ui-sref="about">About</a></li>
  <li><a ui-sref="contact">Contact</a></li>
 </ul>
 </div>
 <div class="container">
 <div ui-view></div>
 </div>
</body>
</html>

app.js

angular.module('app', ['ui.router'])
 .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
 //默认指向
 $urlRouterProvider.otherwise('/home');

 $stateProvider.state('home', {
  url: '/home',
  templateUrl: './components/home/home.tpl.html',
  controller: 'HomeController',
  controllerAs: 'vm'

 }).state('about', {
  url: '/about',
  templateUrl: './components/about/about.tpl.html',
  controller: 'AboutController',
  controllerAs: 'vm'
 }).state('contact', {
  url: '/contact',
  templateUrl: './components/contact/contact.tpl.html',
  controller: 'ContactController',
  controllerAs: 'vm'
 })

 }])

controller中文件格式一直,tpl为view文件以home模块为例:

home.controller.js

angular.module('app')
 .controller('HomeController', HomeController);

HomeController.$inject = ['$scope'];

function HomeController($scope) {
 console.log("HomeController created successfully!!!");
}

home.tpl.html

<h2>Page Home</h2>

对命名做如下规定,所有文件夹都用小写,多词用点号隔开,所有文件都小写,多词用点号分割,控制器以.controller.js结尾,类似的有.service.js,.tpl.html,.directive.js,.filter.js等。

最终运行效果如下:

利用require.js与angular搭建spa应用的方法实例

上述代码能正常运行,但是我们发现一个问题,当前js文件或者说模块较少,我们引入不会有很大的问题,但是当我们的应用变得很大,文件几十甚至上百个,如何处理呢,有人说当然使用构建工具了,一个一个引入多慢呢,构建工具当然可以做到批量引入js文件,但是我们还需要考虑按需加载的问题,举例来说,我们在打开home的时候,about和contact是没必要加载的,但是按照我们传统的模式,所有脚本都完成了加载,这首先增加了http请求次数,脚本过多的加载解析也影响浏览器的渲染,用户体验并不友好,基于此,我们有几种方式来实现,1、基于requirejs来做,这也是本章内容要讲的部分;2、使用webpack分块打包,实现按需加载,后期看时间会加入对应的文章;3、使用oclazyload(可自行google)。本文就以requirejs来实现一下业务模块的按需加载,在此之前首先引入requirejs。

2、引入Requirejs

RequireJS 是一个JavaScript模块加载器。它非常适合在浏览器中使用,但它也可以用在其他脚本环境,就像 Rhino and Node。使用RequireJS加载模块化脚本将提高代码的加载速度和质量,实现的是AMD规范,当然类似的还有CMD规范的实现框架seajs。

Requirejs中,简单的说一个文件一个模块,即是单文件模块,所以对模块的加载其实本质上是对文件的加载。

假设读者已经了解requirejs的基本使用方式。

上一节中,讲到了提了一下controller的注册方式,其中说到了动态注册,当然除了controller之外,还有service、directive等都可以实现动态注册,这也是我们实现按需加载的基础,现在对我们的项目做一下修改,增加requirejs配置文件,main.js

require.config({
 paths:{
 angular:'https://cdn.bootcss.com/angular.js/1.6.0/angular',
 ui_router:'https://cdn.bootcss.com/angular-ui-router/1.0.3/angular-ui-router',
 app:'./app'
 
 },
 shim:{
 angular:{exports:'angular'}
 }
});

require(['angular','./app','ui_router'],function(angular,app){
 angular.element(document).ready(function(){
 angular.bootstrap(document,[app.name]);
 })
})

app.js修改如下:

define(['angular', 'ui_router'], function (angular) {
 var app = angular.module('app', ['ui.router'])
 .config(['$controllerProvider', '$provide', function ($controllerProvider, $provide) {
  app.register = {
  controller: $controllerProvider.register,//动态注册controller
  factory: $provide.factory//动态注册服务
  }
 }])
 .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
  //默认指向
  $urlRouterProvider.otherwise('/home');

  $stateProvider.state('home', {
  url: '/home',
  templateUrl: './components/home/home.tpl.html',
  controller: 'HomeController',
  controllerAs: 'vm',
  resolve: {
   deps: loadCtrl(['./components/home/home.controller'])
  }

  }).state('about', {
  url: '/about',
  templateUrl: './components/about/about.tpl.html',
  controller: 'AboutController',
  controllerAs: 'vm',
  resolve: {
   deps: loadCtrl(['./components/about/about.controller'])
  }
  }).state('contact', {
  url: '/contact',
  templateUrl: './components/contact/contact.tpl.html',
  controller: 'ContactController',
  controllerAs: 'vm',
  resolve: {
   deps: loadCtrl(['./components/contact/contact.controller'])
  }
  })

 }]);
 return app;


 function loadCtrl(path_arr) {
 return ['$q','$rootScope', function ($q,$rootScope) {
  var defered = $q.defer();
  require(path_arr, function () {





$rootScope.$apply(function(){














deffered.resolve();






})
49  });

  return defered.promise;

 }]
 };
})

修改controller注册方式如下:

define(['app'], function (app) {
 app.register.controller('HomeController', HomeController);

 HomeController.$inject = ['$scope'];

 function HomeController($scope) {
 console.log("HomeController created successfully!!!");
 }
})

最后修改修改index.html中脚本引入方式,以及去掉ng-app指令启动方式,angular应用启动已在main.js中通过domready后使用脚本启动。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>demo1</title>
 <script src="https://cdn.bootcss.com/require.js/2.3.3/require.js" data-main="./main"></script>

</head>
<body>
 <div class="nav">
 <ul>
  <li><a ui-sref="home">Home</a></li>
  <li><a ui-sref="about">About</a></li>
  <li><a ui-sref="contact">Contact</a></li>
 </ul>
 </div>
 <div class="container">
 <div ui-view></div>
 </div>
</body>
</html>

最终运行效果如下,可以看到只有在点击了对应的菜单时,才加载了对应的controller:

利用require.js与angular搭建spa应用的方法实例

由于代码简单,注释很少,有疑问可直接提交。

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Javascript的一种模块模式
Mar 22 Javascript
jQuery实现炫酷的鼠标轨迹特效
Feb 01 Javascript
在for循环中length值是否需要缓存
Jul 27 Javascript
JS使用eval解析JSON的注意事项分析
Nov 14 Javascript
JavaScript基础知识及常用方法总结
Jan 10 Javascript
Bootstrap CSS布局之表单
Dec 17 Javascript
javascript实现数据双向绑定的三种方式小结
Mar 09 Javascript
慕课网题目之js实现抽奖系统功能
Sep 19 Javascript
Vue 指令实现按钮级别权限管理功能
Apr 23 Javascript
Vue.js递归组件实现组织架构树和选人功能案例分析
Jul 03 Javascript
vue 使用鼠标滚动加载数据的例子
Oct 31 Javascript
一篇文章带你从零快速上手Rollup
Sep 07 Javascript
ztree简介_动力节点Java学院整理
Jul 19 #Javascript
Angular 1.x个人使用的经验小结
Jul 19 #Javascript
纯js实现的积木(div层)拖动功能示例
Jul 19 #Javascript
vue loadmore组件上拉加载更多功能示例代码
Jul 19 #Javascript
vue引入swiper插件的使用实例
Jul 19 #Javascript
vue loadmore 组件滑动加载更多源码解析
Jul 19 #Javascript
JS实现的走迷宫小游戏完整实例
Jul 19 #Javascript
You might like
有道搜索和IP138的IP的API接口(PHP应用)
2012/11/29 PHP
php 去除html标记--strip_tags与htmlspecialchars的区别详解
2013/06/26 PHP
解析PHP 使用curl提交json格式数据
2013/06/29 PHP
PHP结合JQueryJcrop实现图片裁切实例详解
2014/07/24 PHP
编写跨浏览器的javascript代码必备[js多浏览器兼容写法]
2008/10/29 Javascript
JavaScript 精粹读书笔记(1,2)
2010/02/07 Javascript
再谈javascript面向对象编程
2012/03/18 Javascript
jQuery点击tr实现checkbox选中的方法
2013/03/19 Javascript
js this函数调用无需再次抓获id,name或标签名
2014/03/03 Javascript
JavaScript基础知识学习笔记
2014/12/02 Javascript
js实现商城星星评分的效果
2015/12/29 Javascript
第一章之初识Bootstrap
2016/04/25 Javascript
javascript实现简单的on事件绑定
2016/08/23 Javascript
jstree创建无限分级树的方法【基于ajax动态创建子节点】
2016/10/25 Javascript
JavaScript设计模式之装饰者模式定义与应用示例
2018/07/25 Javascript
[04:11]DOTA2上海特级锦标赛主赛事首日TOP10
2016/03/03 DOTA
python从网络读取图片并直接进行处理的方法
2015/05/22 Python
详解使用python crontab设置linux定时任务
2016/12/08 Python
Python 专题五 列表基础知识(二维list排序、获取下标和处理txt文本实例)
2017/03/20 Python
解决python文件字符串转列表时遇到空行的问题
2017/07/09 Python
解决Ubuntu pip 安装 mysql-python包出错的问题
2018/06/11 Python
详解python--模拟轮盘抽奖游戏
2019/04/12 Python
python实现控制电脑鼠标和键盘,登录QQ的方法示例
2019/07/06 Python
python或C++读取指定文件夹下的所有图片
2019/08/31 Python
python代码能做成软件吗
2020/07/24 Python
CSS3点击按钮实现背景渐变动画效果
2016/10/19 HTML / CSS
CSS3 @keyframes简单动画实现
2018/02/24 HTML / CSS
美国领先的机场停车聚合商:Airport Parking Reservations
2020/02/28 全球购物
Java里面如何创建一个内部类的实例
2015/01/19 面试题
文化与传播毕业生求职信
2014/03/09 职场文书
优秀食品类广告词
2014/03/19 职场文书
三月学雷锋活动总结
2014/06/26 职场文书
2014年医院个人工作总结
2014/12/09 职场文书
新郎新娘答谢词
2015/01/04 职场文书
杭州西湖英语导游词
2015/02/03 职场文书
2015仓库保管员年终工作总结
2015/05/13 职场文书