第1章 介绍
js尽量写到界面的最后
1.0 介绍
AngularJS是一款由Google公司开发维护的前端MVC框架,其克服了HTML在构建应用上的诸多不足,从而降低了开发成本提升了开发效率。
1.1 特点
AngularJS与我们之前学习的jQuery是有一定的区别的,jQuery更准确来说只一个类库(类库指的是一系列函数的集合)以DOM做为驱动(核心),
而AngularJS则一个框架(诸多类库的集合)以数据和逻辑做为驱动(核心)。
框架对开发的流程和模式做了约束,开发者遵照约束进行开发,更注重的实际的业务逻辑。
AngularJS有着诸多特性,最为核心的是:模块化、双向数据绑定、语义化标签、依赖注入等。
与之类似的框架还有BackBone、KnockoutJS、Vue、React等。
1.2 下载
1、通过AngularJS官网下载,不过由于国内特殊的国情,需要翻墙才能访问。
https://angularjs.org/
2、通过npm下载,npm install angular
3、通过bower下载,bower install angular
1.3 体验AngularJS
<!-- 引入angularJS框架 -->
<script src="./libs/angular.min.js"></script>
<!-- -->
<body ng-app>
<!-- 把输入框中的内容放到 msg变量中 -->
<input type="text" ng-model="msg">
<!-- 动态的把msg变量的值拿出展示,只要msg的值发生变化就会动态获取 -->
<h2>{{msg}}</h2>
</body>
1.4 MVC
MVC是一种开发模式,由模型(Model)、视图(View)、控制器(Controller)3部分构成,采用这种开发模式为合理组织代码提供了方便、降低了代码间的耦合度、功能结构清晰可见。
模型(Model)一般用来处理数据(读取/设置),一般指操作数据库。
视图(View)一般用来展示数据,比如通过HTML展示。
控制器(Controller)一般用做连接模型和视图的桥梁。
通过ThinkPHP来演示后端MVC的执行流程,其重点在于理解。
MVC更多应用在后端开发程序里,后被引入到前端开发中,由于受到前端技术的限制便有了一些细节的调整,进而出现了很多MVC的衍生版(子集)如MVVM、MVW、MVP、MV*等。
注:做为初学可以不必过于在意这些概念。
第2章 模块化
2.0 介绍
使用AngularJS构建应用(App)时是以模块化(Module)的方式组织的,即将整个应用划分成若干模块,每个模块都有各自的职责,最终组合成一个整体。
采用模块化的组织方式,可以最大程度的实现代码的复用,可以像搭积木一样进行开发。
2.1 定义应用View视图
<!-- 指定模块 -->
<div class="box" ng-app="App">
!-- 指定控制器 -->
<div ng-controller="DemoContoller"></div>
</div>
一定要先有模块,后有控制器
一个页可以有多个模块,但是不能互想嵌套
一般只会有一个
2.2 定义模块
AngularJS提供了一个全局对象angular,在此全局对象下存在若干的方法,其中angular.module()方法用来定义一个模块。
注:应用(App)其本质也是一个模块(一个比较大的模块)。
代码:
var App = angular.module('App', []);
App就是新创建的模块,这个模块又是一个对象
在此对象下又有N多方法,可以实现具体业务逻辑
App 就是div中的ng-app中的内容
2.3 定义控制器
控制器(Controller)作为连接模型(Model)和视图(View)的桥梁存在,所以当我们定义好了控制器以后也就定义好了模型和视图。
模型(Model)数据是要展示到视图(View)上的,所以需要将控制器(Controller)关联到视图(View)上
通过为HTML标签添加ng-controller属性并赋值相应的控制器(Controller)的名称,就确立了关联关系。
代码:
App.controller('DemoContoller', ['$scope', function ($scope) {}]);
$scope 是一个空对象{},此对象就是Model
DemoContoller 是div中的ng-controller属性的值
第3章 指令
3.0 说明
HTML在构建应用(App)时存在诸多不足之处,AngularJS通过扩展一系列的HTML属性或标签来弥补这些缺陷,
所谓指令就是AngularJS自定义的HTML属性或标签,这些指令都是以ng-做为前缀的,例如ng-app、ng-controller、ng-repeat等。
3.1 内置指令(view(html)中的ng指令)
ng-app="Demo" 模块名称,指定应用根元素,至少有一个元素指定了此属性。
ng-controller="StarsController" 控制器名称,指定控制器
ng-init="name='shuaige';age=10" 用于初始化属性值,相当于$scope.name='shuaige';$scope.age=10;
ng-repeat="str in arr" 遍历数组
ng-switch-when="java" 用来判断某个变量中的值是否是java,跟ng-repeat一起使用可以判断当前对象的值是否是Java。
ng-switch on 选择判断结构。跟ng-switch-when一起使用。<div ng-switch on="type"><div ng-switch-when="java">当type的值是Java时显示</div></div>
ng-show="0" 用来显示或隐藏内容(元素实际存在),1显示,0隐藏
ng-hide="1" 用来显示或隐藏内容(元素实际存在),1隐藏,0显示
ng-if="1" 用来控制元素是否存在(元素可能不存在),1存在,0不存在
ng-src="{{path}}" 用来添加src路径。在angular中要使用此指令添加路径,否则会有页面图片找不到到页面从新刷新的小问题。
ng-href="{{path}}" 用来添加href路径
ng-class="{red: true}" 用来控制类名。用来添加css中的class样式
ng-class="{active: type == 'local'}" 用$scope中的type变量的值来控制active这个类是否添加还是移除。
ng-include 引入模板 <body ng-app="App"><div ng-include="'./header.html'"></div><script>var App = angular.module('App', []);</script></body>
ng-disabled="1" 表单禁用。用来控制元素是否可用,1不可用,0可用
ng-readonly="1" 表单只读。用来控制元素是否只读,1只读,0可修改
ng-checked="1" 单/复选框表单选中。用来控制多选框元素是否选中,1选中,0未选中
ng-selected="1" 下拉框表单选中。用来控制下拉框元素是否选中,1选中,0未选中
ng-bind="name" 用来绑定model模型($scope)中的name属性。可以获取name属性的值。跟{{name}}效果一样
ng-cloak 用来解决页面刷新速度过快导致的闪动问题(可以看到{{}}这个括号),用法<li ng-cloak>{{name}}{{age}}</li>
ng-bind-template 绑定多个数据,用法<li ng-bind-template="{{name}}{{age}}"></li>
ng-model="msg" 绑定数据。要实现数据从视图向模型传递需要借助于表单元素,相当于$scope.msg
ng-click="show()" 单击。用来调用$scope.show = function(){} 这个show方法
ng-click="show('local')" 调用$scope.switch = function(type){} 这个方法。type就等于local。
ng-dblclick="double()" 双击。用来调用$scope.double = function(){}这个double方法
ng-blur="blur()" 失去焦点。用来调用$scope.blur = function(){} 这个blur方法
ng-mouseout="mouseout()" 鼠标移除事件。用来调用$scope.mouseout = function(){}这个mouseout方法
<h1 ng-cloak>{{name}}</h1>
<h1 ng-bind="name"></h1>
<h1 ng-bind-template="{{name}}"></h1>
<h1>{{aa}}</h1>
<h1>{{bb}}</h1>
<ul>
<li ng-repeat="str in arrs">{{str}}</li>
</ul>
<ul>
<li ng-repeat="student in students">{{student.name}}-{{student.age}}</li>
</ul>
<input type="text" ng-if="type"/>
<input type="text" ng-show="type"/>
<input type="text" ng-hide="type"/>
<img ng-src="./img/01.jpg">
<a ng-href="{{path}}">atest</a><br/><br/><br/><br/>
<div ng-include="'./views/one.html'"></div>
<input type="text" ng-disabled="type" />
<input type="text" ng-readonly="type" />
<input type="checkbox" name="sex" value="男" ng-checked="type" />男
<input type="checkbox" name="sex" value="女" ng-checked="type"/>女
<input type="radio" name="gendar" value="男"/>男
<input type="radio" name="gendar" value="女" ng-checked="type"/>女
<select>
<option>中国</option>
<option ng-selected="type">美国</option>
</select>
<input type="text" ng-model="msg"/>
<h1 ng-bind="msg" ng-class="{red:type}"></h1>
<ul ng-switch="msg">
<li ng-switch-when="shuaige">shuaige</li>
<li ng-switch-when="shuaige2">shuaige2</li>
</ul>
<ul ng-repeat="str in arrs" ng-switch="str">
<li ng-switch-when="java">java技术</li>
<li ng-switch-when="css">css技术</li>
<li ng-switch-when="js">js技术</li>
</ul>
<button ng-click="click()">click</button>
<h1 ng-dblclick="dbclick1()">dbclick</h1>
<input type="text" ng-blur="blur()" />
<p ng-mouseout="mouseout()">这是一块区域</p>
3.2 自定义指令
AngularJS允许根据实际业务需要自定义指令,通过angular全局对象下的directive方法实现。
// E element 是一个元素 <tag></tag>
// A attribute 是一个属性 <div tag></div>
// C class 是一个类 <div class="tag"></div>
// M mark replace 必须为true <!-- directive:tag -->备注
代码1:
<div tag></div>
var App = angular.module('App', []);
App.directive('tag', function () {
return {
restrict: 'EA',
template: '<p>hello shuaige</p>'
}
});
界面会显示hello shuaige
代码2:要用localhost访问,否则会显示报错
<div tag></div>
var App = angular.module('App', []);
App.directive('tag', function () {
return {
restrict: 'EA',
templateUrl: './lists.html'
}
});
界面会显示lists.html中的内容
代码3:要用localhost访问,否则会显示报错
<div tag></div>
var App = angular.module('App', []);
App.directive('tag', function () {
return {
restrict: 'EA',
templateUrl: './lists.html',
replace: true
}
});
界面会显示lists.html中的内容,但是外层的标签会去掉。
3.3 具体使用
$scope 是一个空对象{},此对象就是Model
//普通字符串
$scope.name = '李振杰';
//view中取值 {{name}}
//数组
$scope.courses = ['MVC','指令','模块化']
//view中取值 <li ng-repeat="(key, course) in courses">第{{key}}天:{{course}}</li>
ng-repeat="(key, course) in courses"是就遍历courses数组
(key,course) : key是下标,course是游标代表数组当前位置的值。
取值key是{{key}}
取值course是{{course}}
//数组
$scope.stars = [{name: '刘德华', sex: '男', age: 62},{name: '王力宏', sex: '男', age: 40}];
//view中取值
<tr ng-repeat="star in stars">
<td>{{star.name}}</td>
<td>{{star.sex}}</td>
<td>{{star.age}}</td>
</tr>
ng-repeat="star in stars" 是遍历 stars 数组,数组当前位置的变量名为star
{{star.name}},{{star.sex}},{{star.age}} 是获取当前变量中的name,sex,age属性的值。
//数组
$scope.names = [];
//往数组中添加一条数据
$scope.names.push('shuaige');
//从数组中取出一条数据,并且从数组中移除
$scope.names.splice(start,length);
第4章 数据绑定
4.0 说明
AngularJS是以数据做为驱动的MVC框架,所有模型(Model)里的数据经由控制器(Controller)展示到视图(View)中。
所谓数据绑定指的就是将模型(Model)中的数据与相应的视图(View)进行关联,分为单向绑定和双向绑定两种方式。
4.1 单向绑定
单向数据绑定是指将模型(Model)数据,按着写好的视图(View)模板生成HTML标签,然后追加到DOM中显示.
4.2 双向绑定
双向绑定则可以实现模型(Model)数据和视图(View)模板的双向传递
<input type="text" ng-model="msg">
4.3 相关指令
在AngularJS中通过“{{}}”和ng-bind指令来实现模型(Model)数据向视图模板(View)的绑定,
模型数据通过一个内置服务$scope来提供,这个$scope是一个空对象,
通过为这个对象添加属性或者方法便可以在相应的视图(View)模板里被访问。
注:“{{}}”是ng-bind的简写形式,其区别在于通过“{{}}”绑定数据时会有“闪烁”现象,
添加ng-cloak也可以解决“闪烁”现象,通过ng-bind-template可以绑定多个数据。
ng-model 实现视图(View)模板向模型(Model)数据的绑定。
ng-init 初始化模型(Model)也就是$scope
AngularJS对事件也进行了扩展,无需显式的获取DOM元素便可以添加事件,易用性变的更强。
通过在原有事件名称基础上添加ng-做为前缀,然后以属性的形式添加到相应的HTML标签上即可。
如ng-click、ng-dblclick、ng-blur等。
ng-repeat可以将数组或对象数据迭代到视图模板中,ng-switch、on、ng-switch-when可以对数据进行筛选。
第5章 作用域
5.0 说明
通常AngularJS中应用(App)是由若干个视图(View)组合成而成的,而视图(View)又都是HTML元素,并且HTML元素是可以互相嵌套的,
另一方面视图都隶属于某个控制器(Controller),进而控制器之间也必然会产生嵌套关系。
每个控制器(Controller)又都对应一个模型(Model)也就是$scope对象,不同层级控制器(Controller)下的$scope便产生了作用域。
5.1 根作用域
一个AngularJS的应用(App)在启动时会自动创建一个根作用域$rootScope,这个根作用域在整个应用范围(ng-app所在标签以内)都是可以被访问到的。
<div ng-app="App" ng-init="name='shuaige';age=20"></div>
ng-app 所在元素就是应用的根元素
ng-init 为$rootScope添加数据
5.2 子作用域
通过ng-controller指令可以创建一个子作用域,新建的作用域可以访问其父作用域的数据。
$scope.name = '帅哥';
第6章 过滤器
6.0 说明
在AngularJS中使用过滤器格式化展示数据,在“{{}}”中使用“|”来调用过滤器,使用“:”传递参数。
6.1 内置过滤器
currency将数值格式化为货币格式
{{price|currency:'¥'}}
$scope.price = 11.11;
date日期格式化,年(y)、月(M)、日(d)、星期(EEEE/EEE)、时(H/h)、分(m)、秒(s)、毫秒(.sss),也可以组合到一起使用。
{{now|date:'yyyy/MM/dd hh:mm:ss'}}
$scope.now = new Date;
filter在给定数组中选择满足条件的一个子集,并返回一个新数组,其条件可以是一个字符串、对象、函数
{{items|filter:'s'}}
$scope.items = ['html', 'css', 'js']; 从中挑出包含s的数据显示在界面
{{students|filter:{age: 16} }}
$scope.students = [{name: '小红', age: 16},{name: '小明', age: 16},{name: '小米', age: 10}]; 从中挑出age等于16的数据
json将Javascrip对象转成JSON字符串
{{students|json}}
$scope.students = [{name: '小红', age: 16},{name: '小明', age: 16},{name: '小米', age: 10}]; 会显示json字符串
limitTo取出字符串或数组的前(正数)几位或后(负数)几位
{{items|limitTo:-1}}
$scope.items = ['html', 'css', 'js']; 页面只显示js
lowercase将文本转换成小写格式
{{str|lowercase}}
$scope.str = 'hello Angular'; 小写展示数据
uppercase将文本转换成大写格式
{{str|uppercase|limitTo:3}}
$scope.str = 'hello Angular'; 从开始取3位字符,大写展示数据
number数字格式化,可控制小位位数
{{num|number:2}}
$scope.num = '10.2365'; 取小数点两位显示
orderBy对数组进行排序,第2个参数可控制方向
{{items|orderBy: '':true}}
$scope.items = ['html', 'ass', 'js']; 排序,false按照自然顺序正向排序,true按照自然顺序逆向排序
{{students|orderBy: 'age': false}}
$scope.students = [{name: '小红', age: 16},{name: '小明', age: 9},{name: '小米', age: 10}];//按照age排序。false按照自然顺序正向排序,true按照自然顺序逆向排序
6.2 自定义过滤器
除了使用AngularJS内建过滤器外,还可以根业务需要自定义过滤器,通过模块对象实例提供的filter方法自定义过滤器。
//自定义过滤器
App.filter('shuaige', function () {
return function (input) {
return 'hello ' + input;
}
});
//使用过滤器
{{info|shuaige}}
$scope.info = 'shuaige';
第7章 依赖注入
7.0 说明
AngularJS采用模块化的方式组织代码,将一些通用逻辑封装成一个对象或函数,实现最大程度的复用,这导致了使用者和被使用者之间存在依赖关系。
所谓依赖注入是指在运行时自动查找依赖关系,然后将查找到依赖传递给使用者的一种机制。
常见的AngularJS内置服务有$http、$location、$timeout、$rootScope等
7.1 推断式注入
没有明确声明依赖,AngularJS会将函数参数名称当成是依赖的名称。
这种方式会带来一个问题,当代码经过压缩后函数的参数被压缩,这样便会造成依赖无法找到。
AngularJS 内置一些具有特殊功能的“模块”
开发者在开发的时候可以直接使用这些“模块”
<div class="box" ng-controller="DemoController"></div>
App.controller('DemoController', function ($scope, $http) {});
7.2 行内注入
以数组形式明确声明依赖,数组元素都是包含依赖名称的字符串,数组最后一个元素是依赖注入的目标函数。
推荐使用这种方式声明依赖
<div ng-controller="DemoController"></div>
App.controller('DemoController', ['$scope', '$http', function (abc, bcd) {}]);
第8章 服务
8.0 说明
服务是一个对象或函数,对外提供特定的功能
8.1 内建服务
1.$location是对原生Javascript中location对象属性和方法的封装
App.controller('DemoController', ['$scope', '$location', function($scope, $location) {
$scope.absUrl = $location.absUrl();//绝对地址
$scope.url = $location.url();//锚点#后面的内容
$scope.host = $location.host();//地址
$scope.search = $location.search();
$scope.hash = $location.hash();
$scope.protocol = $location.protocol();//协议
$scope.port = $location.port();//端口号
}]);
2.$timeout&$interval对原生Javascript中的setTimeout和setInterval进行了封装。
App.controller('DemoController', ['$scope', '$timeout', '$interval',function ($scope, $timeout, $interval) {
$timeout(function () {
$scope.msg = '执行了';
}, 3000);
var timer = $interval(function () {
$scope.now = new Date;
}, 1000);
$scope.stop = function () {
$interval.cancel(timer);
}
}]);
3.$filter在控制器中格式化数据
App.controller('DemoController', ['$scope', '$filter', function ($scope, $filter) {
// $filter是九种过滤器中任何一个
$scope.price = 11.11;
var currency = $filter('currency');
$scope.price = currency($scope.price);
$scope.str = 'hello angular';
var uppercase = $filter('uppercase');
$scope.str = uppercase($scope.str);
$scope.str1 = $filter('limitTo')($scope.str, 2);
}]);
4.$log打印调试信息
App.controller('DemoController', ['$log', function ($log) {
$log.info('普通信息');
$log.warn('警告信息');
$log.error('错误信息');
$log.log('打印信息');
$log.debug('调试信息');
}]);
5.$http用于向服务端发起异步请求
$http 本质是对XMLHttpRequest对象封装
App.controller('DemoController', ['$scope', '$http', '$log', function ($scope, $http, $log) {
$http({
url: 'example.php',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
params: { // get 参数
name: 'itcast',
sex: '男'
},
data: { // post 传参
age: 10
}
}).success(function (info) {
$log.info(info);// info 就是返回的数据
});
}]);
App.controller('StarController', ['$http', '$scope', '$log', function ($http, $scope, $log) {
$scope.getData = function () {
$http({
url: './stars.php',
method: 'get'
}).success(function (info) {
$scope.stars = info;
});
}
}]);
$http跨域
App.controller('DemoController', ['$http', '$scope', function ($http, $scope) {
$http({
url: 'jsonp.php?a=JSON_CALLBACK',
method: 'jsonp' // 采用JSONP方式
}).success(function (info) {
console.log(info);
});
}]);
请求一下百度天气http://api.map.baidu.com/telematics/v3/weather?callback=JSON_CALLBACK
Weather.controller('WeatherController', ['$scope', '$http', function ($scope, $http) {
$http({
url: 'http://api.map.baidu.com/telematics/v3/weather',
method: 'jsonp',
params: {
location: '北京',
output: 'json',
ak: '0A5bc3c4fb543c8f9bc54b77bc155724',
callback: 'JSON_CALLBACK'
}
}).success(function (info) {
$scope.weatherData = info.results[0].weather_data;
});
}]);
6.同时还支持多种快捷方式如$http.get()、$http.post()、$http.jsonp
8.2 自定义服务
通过上面例子得知,所谓服务是将一些通用性的功能逻辑进行封装方便使用,AngularJS允许将自定义服务。
在介绍服务时曾提到服务本质就是一个对象或函数,所以自定义服务就是要返回一个对象或函数以供使用。
1.factory方法
//定义一个名叫showTime的服务
App.factory('showTime', ['$filter', function ($filter) {
var now = new Date();
var date = $filter('date');
return {
now: date(now, 'y-M-d H:m:s')
}
}]);
//使用服务
App.controller('DemoController', ['$scope', 'showTime', function($scope, showTime) {
$scope.now = showTime.now;
}]);
App.controller('DemoController', ['$scope', '$http', 'showTime', function ($scope, $http, showTime) {}]);
2.service方法
App.service('showTime', ['$filter', function($filter) {
var now = new Date();
var date = $filter('date');
this.now = date(now, 'y-M-d H:mm:ss');
}]);
App.controller('DemoController', ['$scope', 'showTime', function($scope, showTime) {
$scope.now = showTime.now;
}]);
3.value方法定义常量
//本质上一个服务
//从表现形式上是一个常量
//常量就是不变的值与变对量相对应
App.value('author', 'shuaige');
App.controller('DemoController', ['$scope', 'author', function($scope, author) {
$scope.author = author;
}]);
第9章 模块加载
9.0 说明
AngularJS模块可以在被加载和执行之前对其自身进行配置。我们可以在应用的加载阶段配置不同的逻辑。
执行流程
1.启动阶段
开始->浏览器解析DOM树->遇到angular.js停止解析,开始执行脚本->angular监听到DOMContent Loaded事件->启动angular应用
2.初始化阶段
查找模块依赖->寻找ng-app指令->初始化必要组件($injector/$complie/$rootScope)->配置和运行->开始解析DOM树
3.编译链接阶段
$complie遍历DOM树,搜集指令->执行每个指令的complie函数->处理DOM转换,编译模板->调用链接函数,生成实时视图
4.运行阶段
等待事件触发,执行$digest循环->检测到变化,调用$watch函数->再次执行$digest循环,直到没有变化->结束
9.1 配置块
通过config方法实现对模块的配置,AngularJS中的服务大部分都对应一个“provider”,用来执行与对应服务相同的功能或对其进行配置。
比如$log、$http、$location都是内置服务,相对应的“provider”分别是$logProvider、$httpProvider、$locationPorvider。
//配置一个服务
App.config('$logProvider',function($logProvider){});
//配置多个服务
App.config(['$logProvider', '$filterProvider', function ($logProvider, $filterProvider) {
// 禁用debug功能 $log.debug();
$logProvider.debugEnabled(false);
// 默认9个过滤器,通过配置可以新增一些过滤器
$filterProvider.register('capitalize', function () {
// 新增一个过滤器
return function (input) {
return input[0].toUpperCase() + input.slice(1);
}
});
}]);
9.2 运行块
服务也是模块形式存在的对且对外提供特定功能,前面学习中都是将服务做为依赖注入进去的,然后再进行调用,
除了这种方式外我们也可以直接运行相应的服务模块,AngularJS提供了run方法来实现。
不但如此,run方法还是最先执行的,利用这个特点我们可以将一些需要优先执行的功能通过run方法来运行,
比如验证用户是否登录,未登录则不允许进行任何其它操作。
注:此知识点意在了解AngularJS的加载机制。
App.run(['$http',function ($http) {
// 直接调用$http
$http({
url: 'example.php',
method: 'get'
});
}]);
App.run(['$http', '$rootScope', function ($http, $rootScope) {
// 直接调用$http
$http({
url: 'example.php',
method: 'get'
});
// 根作用域
$rootScope.name = '帅哥';
}]);
第10章 路由
10.0 说明
一个应用是由若个视图组合而成的,根据不同的业务逻辑展示给用户不同的视图,路由则是实现这一功能的关键。
angularjs默认支持restful接口
10.1 SPA
SPA(Single Page Application)指的是通单一页面展示所有功能,通过Ajax动态获取数据然后进行实时渲染,
结合CSS3动画模仿原生App交互,然后再进行打包(使用工具把Web应用包一个壳,这个壳本质上是浏览器)变成一个“原生”应用。
在PC端也有广泛的应用,通常情况下使用Ajax异步请求数据,然后实现内容局部刷新,局部刷新的本质是动态生成DOM,
新生成的DOM元素并没有真实存在于文档中,所以当再次刷新页面时新添加的DOM元素会“丢失”,通过单页面应可以很好的解决这个问题。
10.2 路由
在后端开发中通过URL地址可以实现页面(视图)的切换,但是AngularJS是一个纯前端MVC框架,
在开发单页面应用时,所有功能都在同一页面完成,所以无需切换URL地址(即不允许产生跳转),
但Web应用中又经常通过链接(a标签)来更新页面(视图),当点击链接时还要阻止其向服务器发起请求,
通过锚点(页内跳转)可以实现这一点。
1.实现单页面应用需要具备:
a、只有一页面
b、链接使用锚点
通过上面的例子发现在单一页面中可以能过hashchange事件监听到锚点的变化,进而可以实现为不同的锚点准不同的视图,单页面应用就是基于这一原理实现的。
AngularJS对这一实现原理进行了封装,将锚点的变化封装成路由(Route),这是与后端路由的根本区别。
在1.2版前路由功能是包含在AngularJS核心代码当中,之后的版本将路由功能独立成一个模块,下载angular-route.js
spa页面应用特点
把多个项目链接放到同一个页面,不产生页面跳转
把若干功能集成到一个页面
动态生成数据,通过ajax异步获取
为了增强用户体验
可以提升性能
仿制手机app的交互
锚点是前端的路由
hashchange监听锚点变化,绑定给window对象。
路由js写法
<!-- 导航菜单 js写法 -->
<ul>
<li class="active">
<a href="#index">Index</a>
</li>
<li>
<a href="#introduce">Introduce</a>
</li>
<li>
<a href="#contact">Contact Us</a>
</li>
</ul>
<!-- 内容 -->
<div class="content">
Index Page
</div>
// 监听锚点变化然后发送请求
// hashchange事件可以监听锚点变化
window.addEventListener('hashchange', function () {
// 获取锚点
var hash = location.hash;
// 处理#
hash = hash.slice(1);
// 实例对象
var xhr = new XMLHttpRequest;
// 将锚点做为参数传递给服务端进处理
xhr.open('get', '10-01.php?hash=' + hash);
xhr.send(null);
xhr.onreadystatechange = function () {
if(xhr.readyState == 4 && xhr.status == 200) {
var result = xhr.responseText;
// 将返回结果添加到页面
document.querySelector('.content').innerHTML = result;
}
}
});
10.2.1 使用
1.引入angular-route.js
2.实例化模块(App)时,当成依赖传进去(模块名称叫ngRoute)
3.配置路由模块
4.布局模板 - 通过ng-view指令布局模板,路由匹配的视图会被加载渲染到些区域
路由angularjs写法
<!-- 导航菜单 -->
<ul>
<li class="active">
<a href="#/index">Index</a>
</li>
<li>
<a href="#/introduce">Introduce</a>
</li>
<li>
<a href="#/contact">Contact Us</a>
</li>
<li>
<a href="#/list">List</a>
</li>
</ul>
<!-- 内容 -->
<div class="content">
<!-- 占位符 -->
<div ng-view></div>
</div>
<!-- AngularJS核心框架 -->
<script src="./libs/angular.min.js"></script>
<!-- 路由模块理解成插件 -->
<script src="./libs/angular-route.js"></script>
<script>
// 依赖ngRoute模块
var App = angular.module('App', ['ngRoute']);
// 需要对路由模块进行配置,使其正常工作
App.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/index', {
// template: '<h1>index Pages!</h1>',
templateUrl: './abc.html'
})
.when('/introduce', {
template: '<h1>introduce Pages!</h1>'
})
.when('/contact', {
// template: '<h1>contact US Pages!</h1>',
templateUrl: './contact.html',
controller: 'ContactController' // 定义控制器
})
.when('/list', {
templateUrl: './list.html', // 视图模板
controller: 'ListController' // 定义控制器 这个控制器就是控制list.html的
})
.otherwise({
redirectTo: '/index'
});
}]);
// 列表控制器
App.controller('ListController', ['$scope', '$http', function ($scope, $http) {
// 模型数据
$http({
url: '10-02.php',
}).success(function (info) {
$scope.items = info;
});
}]);
App.controller('ContactController', ['$scope', '$http', function ($scope, $http) {
$http({
url: 'contact.php'
}).success(function (info) {
$scope.content = info;
});
}]);
</script>
10.2.1 路由参数
1.提供两个方法匹配路由,分别是when和otherwise,when方法需要两个参数,otherwise方法做为when方法的补充只需要一个参数,其中when方法可以被多次调用。
2.第1个参数是一个字符串,代表当前URL中的hash值
3.第2个参数是一个对象,配置当前路由的参数,如视图、控制器等
a、template 字符串形式的视图模板
b、templateUrl 引入外部视图模板
c、controller 视图模板所属的控制器
d、redirectTo跳转到其它路由
4.获取参数,在控制中注入$routeParams可以获取传递的参数
a)url问号传参数
b)占位符传参
代码:
<!-- AngularJS核心框架 -->
<script src="./libs/angular.min.js"></script>
<!-- 路由模块理解成插件 -->
<script src="./libs/angular-route.js"></script>
<script>
// 依赖ngRoute模块
var App = angular.module('App', ['ngRoute']);
// 需要对路由模块进行配置,使其正常工作
App.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/index/:id/:page/:p', {
templateUrl: 'abc.html',
controller: 'IndexController'
})
.otherwise({
redirectTo: '/index'
});
}]);
// 提供了一个专门负责获取参数的一个服务$routeParams
App.controller('IndexController', ['$scope', '$http', '$routeParams', function ($scope, $http, $routeParams) {
$scope.content = '练习路由功能';
console.log($routeParams);
}]);
</script>
<!--
后端会说明需要什么样的参数
需要一个类型 ID:1,2,3,4
1表示流行 2表示华语 3表示欧美 4表示日韩
-->
<nav>
<a href="#/1"></a>
<a href="#/2"></a>
<a href="#/3"></a>
<a href="#/4"></a>
</nav>
Music.config(['$routeProvider',function($routeProvider){
$routeProvider.when("/:id",{
templateUrl:'./views/list.html',
controller:'ListController'
});
}]);
Music.controller('ListController',['$scope','$http','$routeParams',function($scope,$http,$routeParams){
var id = $routeParams.id;//获取地址上的参数
$http({
url:'./api/list.php',
method:'get',
params:{type:id}//将获取到的参数传给后端
}).success(function(info){
console.log(info);
});
}]);
第11章 其它
11.1 jQuery
在没有引入jQuery的前提下AngularJS实现了简版的jQuery Lite,通过angular.element不能选择元素,但可以将一个DOM元素转成jQuery对象,
如果引提前引入了jQuery则angular.element则完全等于jQuery。
angular.element() 方法可以将一个原生DOM对象转成jquery对象
但是angularJS 只是实现了jquery对象部分方法
// 原生DOM对象
var box = document.querySelector('.box');
var btn = document.querySelector('button');
// 转成jQuery对象
box = angular.element(box);
btn = angular.element(btn);
btn.on('click', function () {
box.css('color', 'red');
});
11.2 bower
基于NodeJS的一个静态资源管理工具,由twitter公司开发维,解决大型网站中静态资源的依赖问题。
1、依赖NodeJS环境和git工具。
2、npm install -g bower安装bower
3、bower search 查找资源信息
4、bower install 安装(下载)资源,通过#号可以指定版本号
5、bower info 查看资源信息
6、bower uninstall 卸载(删除)资源
7、bower init初始化,用来记录资源信息及依赖。
步骤:
node -v 安装node.js
npm -vv
npm install -g brower / npm install -g brower --registry=https://registry.npm.taobao.org
打开git工具/在项目目录下安装jQuery或者其它
brower install jquery / brower install jquery#1.7.2
brower info jquery
brower uninstall jquery
brower init / brower init -config.interactive
其它
angularjs 广播
$scope.$on
$scope.$broadcast
$scope.emit
网友评论