利用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 相关文章推荐
JS实现QQ图片一闪一闪的效果小例子
Jul 31 Javascript
jsp网页搜索结果中实现选中一行使其高亮
Feb 17 Javascript
jQuery插件Tmpl的简单使用方法
Apr 27 Javascript
javascript高级编程之函数表达式 递归和闭包函数
Nov 29 Javascript
JS+CSS实现的漂亮渐变背景特效代码(6个渐变效果)
Mar 25 Javascript
基于Bootstrap的UI扩展 StyleBootstrap
Jun 17 Javascript
JS针对浏览器窗口关闭事件的监听方法集锦
Jun 24 Javascript
jQuery mobile的header和footer在点击屏幕的时候消失的解决办法
Jul 01 Javascript
Javascript将JSON日期格式化
Aug 23 Javascript
详解Vue方法与事件
Mar 09 Javascript
jQuery鼠标悬停内容动画切换效果
Apr 27 jQuery
微信小程序实现卡片层叠滑动效果
Jun 21 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
将兴奋、喜悦和坎加斯带到戴安娜:亚马逊公主
2020/03/03 欧美动漫
漫荒推荐:画风超赞的国风漫画推荐 超长假期不无聊
2020/03/08 国漫
php5 pdo新改动加载注意事项
2008/09/11 PHP
PHP stristr() 函数(不区分大小写的字符串查找)
2010/06/03 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
2015/12/14 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
php写app用的框架整理
2019/09/29 PHP
PHP命名空间(namespace)原理与用法详解
2019/12/11 PHP
在你的网页中嵌入外部网页的方法
2007/04/02 Javascript
js 页面元素的几个用法总结
2013/11/18 Javascript
JavaScript初学者建议:不要去管浏览器兼容
2014/02/04 Javascript
JS获得选取checkbox整行数据的方法
2015/01/28 Javascript
JS实现表单中checkbox对勾选中增加边框显示效果
2015/08/21 Javascript
AngularJS 入门教程之HTML DOM实例详解
2016/07/28 Javascript
Chrome调试折腾记之JS断点调试技巧
2017/09/11 Javascript
使用JS获取SessionStorage的值
2018/01/12 Javascript
基于Vue2实现简易的省市区县三级联动组件效果
2018/11/05 Javascript
vue与iframe之间的信息交互的实现
2020/04/08 Javascript
原生js中运算符及流程控制示例详解
2021/01/05 Javascript
[01:38]2018DOTA2亚洲邀请赛主赛事第二日现场采访 神秘商人痛陈生计不易
2018/04/05 DOTA
Python 使用requests模块发送GET和POST请求的实现代码
2016/09/21 Python
Python操作Redis之设置key的过期时间实例代码
2018/01/25 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
2018/02/03 Python
Python2 Selenium元素定位的实现(8种)
2019/02/25 Python
python爬虫的一个常见简单js反爬详解
2019/07/09 Python
Python栈的实现方法示例【列表、单链表】
2020/02/22 Python
Python连接mysql数据库及简单增删改查操作示例代码
2020/08/03 Python
Python 带星号(* 或 **)的函数参数详解
2021/02/23 Python
高等教育专业自荐信范文
2014/03/26 职场文书
运动会新闻稿
2015/07/17 职场文书
python3使用diagrams绘制架构图的步骤
2021/04/08 Python
MySQL之高可用集群部署及故障切换实现
2021/04/22 MySQL
Redis6.0搭建集群Redis-cluster的方法
2021/05/08 Redis
聊聊Lombok中的@Builder注解使用教程
2021/11/17 Java/Android
MySQL的存储函数与存储过程的区别解析
2022/04/08 MySQL
Python使用pandas导入csv文件内容的示例代码
2022/12/24 Python