随说:
笔者只是将 《AngularJS权威教程》这本书读了一遍,并且将里面能列举的内容用自己的话理解了一遍然后整理出来,编写顺序是按书本顺序作整理
1、 AngularJS数据绑定#
- 引入angular.js
- 在某个DOM元素上,明确设置ng-app属性(只有被ng-app属性的DOM元素区域才会受AngularJS影响)
- ng-model属性是AngularJS的一个指令,将内部数据模型对象的name绑定到文本输入字段上
- 数据绑定的格式{{ name }}
<!DOCTYPE html>
// 设置ng-app属性
<html ng-app>
<head>
<title>Simple app</title>
// 引入JS
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js">
</script>
</head>
<body>
// 可以这样理解,设置该DOM元素value值的KEY为name,然后可以通过{{ key }} , 获取该value
<input ng-model="name" type="text" placeholder="Your name">
// 绑定数据
<h1>Hello {{ name }}</h1>
</body>
</html>
再看一个例子
<!doctype html>
<html ng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js"></script>
</head>
<body>
// DOM元素上 ng-controller 声明所有被它包含的元素都属于某个控制器。
<div ng-controller="MyController">
// 这里的{{clock}} 就是相当于这个值 $scope.clock , 也就是Date()函数的范围值
<h1>Hello {{ clock }}!</h1>
</div>
<script type="text/javascript">
// MyController 函数接收了两个参数, $scope , $timeout
function MyController($scope, $timeout) {
var updateClock = function() {
$scope.clock = new Date();
$timeout(function() {
updateClock();
}, 1000);
};
updateClock();
};
</script>
</body>
</html>
2、AngularJS模块#
AngularJS模块是定义应用的最主要方式,模块包含了主要的应用代码,一个应用可以包含多个模块,每一个模块都包含了定义具体功能的代码
模块定义代码 :
// 第一个参数 : 模块名称
// 第二个参数 : 依赖列表
angular.module('name', []);
3、AngularJS作用域 - $scope#
4、AngularJS控制器#
AngularJS的控制器是一个函数,用来向视图的作用域$scope中添加额外的功能。我们用它来给作用域对象设置初始状态,并添加自定义行为。
新建一个js文件。(一般以业务命名)
例如下面 app.js
在app.js下写上以下代码
// 定义一个名字为app的 模块。
var app = angular.module('app', []);
// 创建一个新的控制器,AngularJS会生成并传递一个新的$scope给这个控制器,
app.controller('FirstController', function($scope) {
// 定义一个成员message并初始化值为“hello”
$scope.message = "hello";
});
AngularJS允许在$scope上升至包括对象在内的任何类型的数据,并且在视图中还可以展示对象的属性。
例如 :
var app = angular.module('myApp', []);
// 创建一个名字叫MyController的控制器
app.controller('MyController', function($scope) {
// 在MyController上创建一个person对象,并为这个对象创建一个名字为name 的属性,初始化值为Ari Lerner
$scope.person = {
name: 'Ari Lerner'
};
});
<div ng-app="myApp">
// 在拥有ng-controller="MyController"的DOM元素内,或者任何子缘故中,都可以访问person对象,因为它是定义在$scope上的。
<div ng-controller="MyController">
<h1>{{ person }}</h1>
and their name: <h2>{{ person.name }}</h2>
</div>
</div>
控制器之间还可以嵌套,请看以下例子###
先创建两个控制器
app.controller('ParentController', function($scope) {
$scope.person = {greeted: false};
});
app.controller('ChildController', function($scope) { $scope.sayHello = function() {
$scope.person.name = 'Ari Lerner'; };
});
下面是实现,将ChildController嵌套于ParentController内部,那childController的$scope对象的父级作用域就是ParentController的$scope对象。
我们可以在子作用域中,访问ParentController父作用域的内容。
<div ng-controller="ParentController">
<div ng-controller="ChildController">
<a ng-click="sayHello()">Say hello</a>
</div>
{{ person }}
</div>
在ChildController并没有定义person对象,可是却可以访问出对象,这就是控制器的嵌套关系,当子作用域中不存在对象时,会自动往上找,根作用域是rootScope
关于嵌套作用域之间,对象中的值的关系
// HTML代码
<div ng-controller="SomeController">
{{ someBareValue }}
<button ng-click="someAction()">Communicate to child</button>
<div ng-controller="ChildController">
{{ someBareValue }}
<button ng-click="childAction()">Communicate to parent</button>
</div>
</div>
// JavaScript代码
angular.module('myApp', [])
.controller('SomeController', function($scope) {
$scope.someBareValue = 'hello computer';
$scope.someAction = function() {
$scope.someBareValue = 'hello human, from parent';
};
})
.controller('ChildController', function($scope) {
$scope.childAction = function() {
$scope.someBareValue = 'hello human, from child';
};
});
例子分析。
点击AAAA ,执行someAction() 函数,someBareValue的值这个时候是属于SomeController这个作用域下的,修改为'hello human, from parent',下面是点击AAAA后的执行结果
可以看到,在ChildController作用域下的someBareValue也改变了。由于继承关系,在ChildController作用域下的someBareValue实际上是通过父级对象从而获取出来的。
那这个时候,如果点击BBBBB,则会执行childAction()函数,也会修改someBareValue的值。效果如下
ChildController作用域下的someBareValue改变了,可是父级对象中someBareValue并没有改变,这说明
子控制器是复制而非引用someBareValue的值的,JavaScript对象要么是值复制,要么是引用复制。字符窜、数字、和布尔型变量是值复制,数组、对象、和函数则是引用复制####
5、AngularJS表达式#
例如前面用到的 {{}} 也是一个表达式
用 {{}} 符号将一个变量绑定到$scope上的写法本质上就是一个表达式 :{{ expression }}
AngularJS在执行$digest脏循环的过程中,会自动解释表达式,那如何手动解析表达式?
$parse服务####
在控制器中注入$parse服务(就是在创建contriller的时候,将$parse作为参数传入去。)
angular.module("myApp", [])
.controller('MyController', function($scope,$parse) {
// $watch的使用,就是,监测ng-model="expr",的输入,并且将新值,旧值,作用域返回
$scope.$watch('expr', function(newVal, oldVal, scope) {
if (newVal !== oldVal) {
// 注入$parse后就可以使用,用$parse设置parseFun,就等于利用了$parse服务解释了得到的新值。
var parseFun = $parse(newVal);
// 定义parsedValue,并且调用parseFun,以此实现手动解析表达式
$scope.parsedValue = parseFun(scope);
}
});
});
HTML代码
<div ng-controller="MyController"> <input ng-model="expr"
type="text"
placeholder="Enter an expression" />
<h2>{{ parseValue }}</h2>
</div>
$interpolate服务
字符窜模板中做插值操作,利用了AngularJS 插值字符窜
<div ng-app="MyApp">
<div ng-controller="MyController">
<input ng-model="myName" type="text" placeholder="Type Your Name">
<textarea ng-model="myTextarea" cols="30" rows="10"></textarea>
<div ng-bind="interpolatedValue"></div>
</div>
</div>
angular.module("MyApp", [])
// 在控制器中,我们设置了$watch来监视邮件正文的变化,并将myTextarea属性的值,进行字符插值后的结果赋值给myName属性
.controller("MyController", function($scope, $interpolate){
$scope.$watch("myTextarea", function(newVal, oldVal, scope){
var interpolatedFunc = $interpolate(' templeat : ' + newVal);
// 将input绑定的值,传入myName中
// interpolatedValue就是经过插值后的新值。
$scope.interpolatedValue = interpolatedFunc({myName: $scope.myName});
});
});
标识替换
假如你不想用 {{ }} 标识开始与结束,你可以通过$inter polateProvider 进行配置
startSymbol() 方法修改标识开始的符号
endSymbo() 方法修改标识结束的符号
angular.module('emailParser', [])
.config(['$interpolateProvider', function($interpolateProvider) {
$interpolateProvider.startSymbol('__');
$interpolateProvider.endSymbol('__');
}])
6、AngularJS过滤器#
过滤器就是用来过滤数据,使数据以你希望的形式展示出来,AngularJS有许多实用的内置过滤器。
使用过滤器有两种形式,HTML中调用过滤器,与JavaScript中调用过滤器
在HTML中的模板绑定符号{{}}内通过 | 符号来调用过滤器
例如 :
{{ name | uppercase }}
在JavaScript代码中可以通过$filter 来调用过滤器。
例如 :
app.controller('DemoController', ['$scope', '$filter',
function($scope, $filter) {
$scope.name = $filter('uppercase')('Ari');
}]);
注意,可以用 | 符号作为分隔符来同时使用多个过滤器####
更多过滤器使用用法请参考这里
7、AngularJS指令#
创建自定义元素的函数称作指令,用.directive()方法创建,
.directive() 指令的使用。
例如,我们自己定义一个标签 <myDir></myDir>
<div>
<my-dir></my-dir>
</div>
angular.module('myApp', [])
.directive('myDir', function() {
return { restrict: 'E',
replace: true,
template: '<a href="http://google.com">简单来说,你在上面看到的<my-dir>表情已经没了</a>' };
});
结果,<my-dir></my-dir>被替换掉
<html ng-app>
<head>
<title>Simple app</title>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.js">
</script>
</head>
<body>
<div>
<a href="http://google.com">简单来说,你在上面看到的<my-dir>表情已经没了</a>
</div>
</body>
</html>
放一个自己的整理的例子
angular.module('myApp', [])
.directive('myDirective', function() {
return {
//字符窜, 可选,在DOM中以何种形式被声明,E(元素),A(属性) , C (类名), M(注释)可单独或者混合使用
restrict: String,
//
priority: Number,
// 布尔型参数,告诉AngularJS停止运行当前元素上比本指令优先级低的指令。
terminal: Boolean,
// 字符串或函数,可选,模板替换。
template: String or Template Function:
// 字符窜货函数,可选,一个可以接受两个参数的函数,并返回一个外部HTML文件路径的字符窜
function(tElement, tAttrs) (...},
// 模板的URL
templateUrl: String,
// 布尔型,可选 ,默认为false , 如果设置必须为true,
// false代表模板会被当作子元素插入到调用此指令的元素内部
replace: Boolean or String,
// 布尔型或对象,可选,默认为false
// 为true时,会自动从父作用域中继承并创建一个新的作用域
//
scope: Boolean or Object,
transclude: Boolean,
controller: String or
function(scope, element, attrs, transclude, otherInjectables) { ... }, controllerAs: String,
require: String,
link: function(scope, iElement, iAttrs) { ... },
compile: //
function(tElement, tAttrs, transclude) {
return {
pre: function(scope, iElement, iAttrs, controller) { ... },
post: function(scope, iElement, iAttrs, controller) { ... }
}
// 或者
return function postLink(...) { ... }
}
};
});
指令是AngularJS中用的最多,最常用的功能,更多详细请看这里