利用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判断浏览器是否是IE的比较好的办法
May 08 Javascript
JS的递增/递减运算符和带操作的赋值运算符的等价式
Dec 08 Javascript
JavaScrip单线程引擎工作原理分析
Sep 04 Javascript
通过jQuery源码学习javascript(二)
Dec 27 Javascript
jQuery中map()方法用法实例
Jan 06 Javascript
jquery实现隐藏在左侧的弹性弹出菜单效果
Sep 18 Javascript
jQuery动画效果实现图片无缝连续滚动
Jan 12 Javascript
JS实现json的序列化和反序列化功能示例
Jun 13 Javascript
浅谈vuex 闲置状态重置方案
Jan 04 Javascript
JS中通过url动态获取图片大小的方法小结(两种方法)
Oct 31 Javascript
ES6 Iterator接口和for...of循环用法分析
Jul 31 Javascript
Vue h函数的使用详解
Feb 18 Vue.js
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
介绍一些PHP判断变量的函数
2012/04/24 PHP
php魔术变量用法实例详解
2014/11/13 PHP
ThinkPHP设置禁止百度等搜索引擎转码(简单实用)
2016/02/15 PHP
YII Framework框架教程之安全方案详解
2016/03/14 PHP
PHP实现动态创建XML文档的方法
2018/03/30 PHP
根据分辨率不同,调用不同的css文件
2006/07/07 Javascript
用js查找法实现当前栏目的高亮显示的代码
2007/11/24 Javascript
IE 条件注释详解总结(附实例代码)
2009/08/29 Javascript
自己封装的常用javascript函数分享
2015/01/07 Javascript
javascript实现拖动元素交换位置
2015/11/29 Javascript
jQuery下拉菜单的实现代码
2016/11/03 Javascript
详解Angular 4.x 动态创建组件
2017/04/25 Javascript
vue init webpack myproject构建项目 ip不能访问的解决方法
2018/03/20 Javascript
浅谈AngularJS中$http服务的简单用法
2018/05/15 Javascript
浅谈Vue使用Cascader级联选择器数据回显中的坑
2020/10/31 Javascript
vue-calendar-component 封装多日期选择组件的实例代码
2020/12/04 Vue.js
python 简易计算器程序,代码就几行
2009/08/29 Python
Python的randrange()方法使用教程
2015/05/15 Python
Python使用matplotlib实现在坐标系中画一个矩形的方法
2015/05/20 Python
Python实现处理逆波兰表达式示例
2018/07/30 Python
Python button选取本地图片并显示的实例
2019/06/13 Python
使用Filter过滤python中的日志输出的实现方法
2019/07/17 Python
python并发爬虫实用工具tomorrow实用解析
2019/09/25 Python
如何在django中添加日志功能
2020/02/06 Python
Python docutils文档编译过程方法解析
2020/06/23 Python
css3新单位vw、vh的使用教程
2018/03/23 HTML / CSS
CSS3 rgb and rgba(透明色)的使用详解
2020/09/25 HTML / CSS
美国著名的团购网站:Woot
2016/08/02 全球购物
英国街头品牌:Bee Inspired Clothing
2018/02/12 全球购物
英国玛莎百货新西兰:Marks & Spencer New Zealand
2019/07/21 全球购物
研发工程师的岗位职责
2013/11/18 职场文书
党支部公开承诺书
2014/03/28 职场文书
小学班主任评语大全
2014/04/23 职场文书
公共场所禁烟倡议书
2014/08/30 职场文书
2015年八一建军节慰问信
2015/03/23 职场文书
先进基层党组织主要事迹材料
2015/11/03 职场文书