ZhangYang's Blog

Angular

AngularJS 简介

指令

  • ng-app 指令告诉 AngularJS,
    元素是 AngularJS 应用程序 的”所有者”
  • ng-model 指令把输入域的值绑定到应用程序变量 name
1
2
3
4
<div ng-app="">
<p>名字 : <input type="text" ng-model="name"></p>
<h1>Hello {{name}}</h1>
</div>
  • ng-bind 指令把应用程序变量 name 绑定到某个段落的 innerHTML
  • ng-init 指令初始化 AngularJS 应用程序变量
1
2
3
4
5
6
7
8
9
10
11
<div ng-app="" ng-init="firstName='John'">
<p>姓名为 <span ng-bind="firstName"></span></p>
</div>
<div data-ng-app="" data-ng-init="firstName='John'">
<p>姓名为 <span data-ng-bind="firstName"></span></p>
</div>

表达式

  • AngularJS 表达式写在双大括号内:

应用

  • ng-app指令定义了应用
  • ng-controller 定义了控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div ng-app="myApp" ng-controller="myCtrl">
名: <input type="text" ng-model="firstName"><br>
姓: <input type="text" ng-model="lastName"><br>
<br>
姓名: {{firstName + " " + lastName}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName= "John";
$scope.lastName= "Doe";
});
</script>

AngularJS 表达式

  • AngularJS 表达式写在双大括号内:
1
2
3
<div ng-app="">
<p>我的第一个表达式: {{ 5 + 5 }}</p>
</div>

AngularJS 数字

  • AngularJS 数字就像 JavaScript 数字
1
2
3
4
5
<div ng-app="" ng-init="quantity=1;cost=5">
<p>总价: {{ quantity * cost }}</p>
</div>
  • 使用 ng-bind 的相同实例
1
2
3
4
5
<div ng-app="" ng-init="quantity=1;cost=5">
<p>总价: <span ng-bind="quantity * cost"></span></p>
</div>

AngularJS 表达式

  • AngularJS 表达式写在双大括号内:
1
2
3
<div ng-app="">
<p>我的第一个表达式: {{ 5 + 5 }}</p>
</div>

AngularJS 数字

  • AngularJS 数字就像 JavaScript 数字
1
2
3
4
5
<div ng-app="" ng-init="quantity=1;cost=5">
<p>总价: {{ quantity * cost }}</p>
</div>
  • 使用 ng-bind 的相同实例
1
2
3
4
5
<div ng-app="" ng-init="quantity=1;cost=5">
<p>总价: <span ng-bind="quantity * cost"></span></p>
</div>

AngularJS 字符串

  • AngularJS 字符串就像 JavaScript 字符串
1
2
3
4
5
<div ng-app="" ng-init="firstName='John';lastName='Doe'">
<p>姓名: {{ firstName + " " + lastName }}</p>
</div>
  • 使用 ng-bind 的相同实例
1
2
3
4
5
<div ng-app="" ng-init="firstName='John';lastName='Doe'">
<p>姓名: <span ng-bind="firstName + ' ' + lastName"></span></p>
</div>

AngularJS 对象

  • AngularJS 对象就像 JavaScript 对象
1
2
3
4
5
<div ng-app="" ng-init="person={firstName:'John',lastName:'Doe'}">
<p>姓为 {{ person.lastName }}</p>
</div>
  • 使用 ng-bind 的相同实例
1
2
3
4
5
<div ng-app="" ng-init="person={firstName:'John',lastName:'Doe'}">
<p>姓为 <span ng-bind="person.lastName"></span></p>
</div>

AngularJS 数组

  • AngularJS 数组就像 JavaScript 数组
1
2
3
4
5
<div ng-app="" ng-init="points=[1,15,19,2,40]">
<p>第三个值为 {{ points[2] }}</p>
</div>
  • 使用 ng-bind 的相同实例
1
2
3
4
5
<div ng-app="" ng-init="points=[1,15,19,2,40]">
<p>第三个值为 <span ng-bind="points[2]"></span></p>
</div>

AngularJS 表达式 与 JavaScript 表达式

  • 类似于 JavaScript 表达式,AngularJS 表达式可以包含字母,操作符,变量。
  • 与 JavaScript 表达式不同,AngularJS 表达式可以写在 HTML 中。
  • 与 JavaScript 表达式不同,AngularJS 表达式不支持条件判断,循环及异常。
  • 与 JavaScript 表达式不同,AngularJS 表达式支持过滤器

ngularJS 指令

  • ng-app 指令初始化一个 AngularJS 应用程序。
  • ng-init 指令初始化应用程序数据。
  • ng-model 指令把元素值(比如输入域的值)绑定到应用程序
1
2
3
4
5
<div ng-app="" ng-init="firstName='John'">
<p>在输入框中尝试输入:</p>
<p>姓名:<input type="text" ng-model="firstName"></p>
<p>你输入的为: {{ firstName }}</p>
</div>

数据绑定

  • 表达式是一个 AngularJS 数据绑定表达
1
2
3
4
5
6
7
8
9
10
<div ng-app="" ng-init="quantity=1;price=5">
<h2>价格计算器</h2>
数量: <input type="number" ng-model="quantity">
价格: <input type="number" ng-model="price">
<p><b>总价:</b> {{ quantity * price }}</p>
</div>

重复 HTML 元素

  • ng-repeat 指令会重复一个 HTML 元素
1
2
3
4
5
6
7
8
<div ng-app="" ng-init="names=['Jani','Hege','Kai']">
<p>使用 ng-repeat 来循环数组</p>
<ul>
<li ng-repeat="x in names">
{{ x }}
</li>
</ul>
</div>
  • ng-repeat 指令用在一个对象数组上
1
2
3
4
5
6
7
8
9
10
11
12
13
<div ng-app="" ng-init="names=[
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}]">
<p>循环对象:</p>
<ul>
<li ng-repeat="x in names">
{{ x.name + ', ' + x.country }}
</li>
</ul>
</div>

ng-app 指令

  • ng-app 指令在网页加载完毕时会自动引导(自动初始化)应用程序

ng-init 指令

  • ng-init 指令为 AngularJS 应用程序定义了 初始值

ng-model 指令

  • ng-model 指令 绑定 HTML 元素 到应用程序数据

ng-repeat 指令

  • ng-repeat 指令对于集合中(数组中)的每个项会 克隆一次 HTML 元素

创建自定义的指令

  • .directive 函数来添加自定义的指令
  • 要调用自定义指令,HTML 元素上需要添加自定义指令名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body ng-app="myApp">
<runoob-directive></runoob-directive>
<script>
var app = angular.module("myApp", []);
app.directive("runoobDirective", function() {
return {
template : "<h1>自定义指令!</h1>"
};
});
</script>
</body>

限制使用

  • 通过添加 restrict 属性,restrict 默认值为 EA, 即可以通过元素名和属性名来调用指令
  • E 作为元素名使用
  • A 作为属性使用
  • C 作为类名使用
  • M 作为注释使用
1
2
3
4
5
6
7
var app = angular.module("myApp", []);
app.directive("runoobDirective", function() {
return {
restrict : "A",
template : "<h1>自定义指令!</h1>"
};
});

AngularJS模型

  • ng-model 指令用于绑定应用程序数据到 HTML 控制器(input, select, textarea)的值

ng-model 指令

  • ng-model 指令可以将输入域的值与 AngularJS 创建的变量绑定
1
2
3
4
5
6
7
8
9
10
<div ng-app="myApp" ng-controller="myCtrl">
名字: <input ng-model="name">
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "John Doe";
});
</script>

双向绑定

  • 双向绑定,在修改输入域的值时, AngularJS 属性的值也将修改
1
2
3
4
5
6
7
8
9
10
11
<div ng-app="myApp" ng-controller="myCtrl">
名字: <input ng-model="name">
<h1>你输入了: {{name}}</h1>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "John Doe";
});
</script>

验证用户输入

1
2
3
4
5
<form ng-app="" name="myForm">
Email:
<input type="email" name="myAddress" ng-model="text">
<span ng-show="myForm.myAddress.$error.email">不是一个合法的邮箱地址</span>
</form>

应用状态

  • ng-model 指令可以为应用数据提供状态值(invalid, dirty, touched, error)
1
2
3
4
5
6
7
8
<form ng-app="" name="myForm" ng-init="myText = 'test@runoob.com'">
Email:
<input type="email" name="myAddress" ng-model="myText" required></p>
<h1>状态</h1>
{{myForm.myAddress.$valid}}
{{myForm.myAddress.$dirty}}
{{myForm.myAddress.$touched}}
</form>

CSS 类

  • ng-model 指令基于它们的状态为 HTML 元素提供了 CSS 类
1
2
3
4
5
6
7
8
9
10
input.ng-invalid {
background-color: lightblue;
}
</style>
<body>
<form ng-app="" name="myForm">
输入你的名字:
<input name="myAddress" ng-model="text" required>
</form>

AngularJS Scope

  • Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带
1
2
3
4
5
6
7
8
9
10
11
12
13
<div ng-app="myApp" ng-controller="myCtrl">
<h1>{{carname}}</h1>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.carname = "Volvo";
});
</script>

Scope 概述

  • View(视图), 即 HTML。
  • Model(模型), 当前视图中可用的数据。
  • Controller(控制器), 即 JavaScript 函数,可以添加或修改属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div ng-app="myApp" ng-controller="myCtrl">
<input ng-model="name">
<h1>{{greeting}}</h1>
<button ng-click='sayHello()'>点我</button>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.name = "Runoob";
$scope.sayHello = function() {
$scope.greeting = 'Hello ' + $scope.name + '!';
};
});
</script>

Scope 作用范围

  • 在以上两个实例中,只有一个作用域 scope,所以处理起来比较简单
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="x in names">{{x}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = ["Emil", "Tobias", "Linus"];
});
</script>

根作用域

  • $rootScope 可作用于整个应用中。是各个 controller 中 scope 的桥梁。用 rootscope 定义的值,可以在各个 controller 中使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div ng-app="myApp" ng-controller="myCtrl">
<h1>{{lastname}} 家族成员:</h1>
<ul>
<li ng-repeat="x in names">{{x}} {{lastname}}</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $rootScope) {
$scope.names = ["Emil", "Tobias", "Linus"];
$rootScope.lastname = "Refsnes";
});
</script>

AngularJS 过滤器

  • 过滤器可以使用一个管道字符(|)添加到表达式和指令中

AngularJS 过滤器

  • AngularJS 过滤器可用于转换数据
  • currency 格式化数字为货币格式
  • filter 从数组项中选择一个子集
  • lowercase 格式化字符串为小写
  • orderBy 根据某个表达式排列数组
  • uppercase 格式化字符串为大写

表达式中添加过滤器

  • 过滤器可以通过一个管道字符(|)和一个过滤器添加到表达式中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div ng-app="myApp" ng-controller="personCtrl">
<p>姓名为 {{ lastName | uppercase }}</p>
</div>
<script>
var app = angular.module('myApp', [])
app.controller('personCtrl', function($scope) {
$scope.firstName = "John",
$scope.lastName = "Doe",
$scope.fullName = function() {
return $scope.firstName + " " + $scope.lastName;
}
});
</script>

currency 过滤器

  • currency 过滤器将数字格式化为货币格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div ng-app="myApp" ng-controller="costCtrl">
数量: <input type="number" ng-model="quantity">
价格: <input type="number" ng-model="price">
<p>总价 = {{ (quantity * price) | currency }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('costCtrl', function($scope) {
$scope.quantity = 1;
$scope.price = 9.99;
});
</script>

向指令添加过滤器

  • orderBy 过滤器根据表达式排列数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div ng-app="myApp" ng-controller="namesCtrl">
<p>循环对象:</p>
<ul>
<li ng-repeat="x in names | orderBy:'country'">
{{ x.name + ', ' + x.country }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', [])
.controller('namesCtrl', function($scope) {
$scope.names = [
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}
];
});
</script>

过滤输入

  • filter 过滤器从数组中选择一个子集
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div ng-app="myApp" ng-controller="namesCtrl">
<p>输入过滤:</p>
<p><input type="text" ng-model="test"></p>
<ul>
<li ng-repeat="x in names | filter:test | orderBy:'country'">
{{ (x.name | uppercase) + ', ' + x.country }}
</li>
</ul>
</div>
<script>
angular.module('myApp', []).controller('namesCtrl', function($scope) {
$scope.names = [
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}
];
});
</script>

自定义过滤器

  • 以下实例自定义一个过滤器 reverse,将字符串反转
1
2
3
4
5
6
7
8
9
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.msg = "Runoob";
});
app.filter('reverse', function() { //可以注入依赖
return function(text) {
return text.split("").reverse().join("");
}
});

AngularJS 服务(Service)

  • AngularJS 中你可以创建自己的服务,或使用内建服务

服务

  • 在 AngularJS 中,服务是一个函数或对象,可在你的 AngularJS 应用中使用
  • $location 服务,它可以返回当前页面的 URL 地址
1
2
3
4
5
6
7
8
9
10
11
12
13
<div ng-app="myApp" ng-controller="myCtrl">
<p> 当前页面的url:</p>
<h3>{{myUrl}}</h3>
</div>
<p>该实例使用了内建的 $location 服务获取当前页面的 URL。</p>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $location) {
$scope.myUrl = $location.absUrl();
});
</script>

使用服务

  • AngularJS 会一直监控应用,处理事件变化, AngularJS 使用 $location 服务比使用 window.location 对象更好

$http 服务

  • $http 是 AngularJS 应用中最常用的服务,服务向服务器发送请求,应用响应服务器传送过来的数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div ng-app="myApp" ng-controller="myCtrl">
<p>欢迎信息:</p>
<h1>{{myWelcome}}</h1>
</div>
<p> $http 服务向服务器请求信息,返回的值放入变量 "myWelcome" 中。</p>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("welcome.htm").then(function (response) {
$scope.myWelcome = response.data;
});
});
</script>

$timeout 服务

  • AngularJS $timeout 服务对应了 JS window.setTimeout 函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<p>两秒后显示信息:</p>
<h1>{{myHeader}}</h1>
</div>
<p>$timeout 访问在规定的毫秒数后执行指定函数。</p>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $timeout) {
$scope.myHeader = "Hello World!";
$timeout(function () {
$scope.myHeader = "How are you today?";
}, 2000);
});
</script>

$interval 服务

  • AngularJS $interval 服务对应了 JS window.setInterval 函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div ng-app="myApp" ng-controller="myCtrl">
<p>现在时间是:</p>
<h1>{{theTime}}</h1>
</div>
<p>$interval 访问在指定的周期(以毫秒计)来调用函数或计算表达式。</p>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $interval) {
$scope.theTime = new Date().toLocaleTimeString();
$interval(function () {
$scope.theTime = new Date().toLocaleTimeString();
}, 1000);
});
</script>

创建自定义服务

  • 创建访问自定义服务,链接到你的模块中
1
2
3
4
5
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
  • 要使用访问自定义服务,需要在定义控制器的时候独立添加,设置依赖关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div ng-app="myApp" ng-controller="myCtrl">
<p>255 的16进制是:</p>
<h1>{{hex}}</h1>
</div>
<p>自定义服务,用于转换16进制数:</p>
<script>
var app = angular.module('myApp', []);
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.controller('myCtrl', function($scope, hexafy) {
$scope.hex = hexafy.myFunc(255);
});
</script>

过滤器中,使用自定义服务

  • 当你创建了自定义服务,并连接到你的应用上后,你可以在控制器,指令,过滤器或其他服务中使用它
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div ng-app="myApp">
在过滤器中使用服务:
<h1>{{255 | myFormat}}</h1>
</div>
<script>
var app = angular.module('myApp', []);
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.filter('myFormat',['hexafy', function(hexafy) {
return function(x) {
return hexafy.myFunc(x);
};
}]);
</script>
  • 在对象数组中获取值时你可以使用过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div ng-app="myApp" ng-controller="myCtrl">
<p>在获取数组 [255, 251, 200] 值时使用过滤器:</p>
<ul>
<li ng-repeat="x in counts">{{x | myFormat}}</li>
</ul>
<p>过滤器使用服务将10进制转换为16进制。</p>
</div>
<script>
var app = angular.module('myApp', []);
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.filter('myFormat',['hexafy', function(hexafy) {
return function(x) {
return hexafy.myFunc(x);
};
}]);
app.controller('myCtrl', function($scope) {
$scope.counts = [255, 251, 200];
});
</script>

AngularJS Select(选择框)

  • AngularJS 可以使用数组或对象创建一个下拉列表选项

使用 ng-options 创建选择框

  • 在 AngularJS 中我们可以使用 ng-option 指令来创建一个下拉列表,列表项通过对象和数组循环输出
1
2
3
4
5
6
7
8
9
10
11
12
13
<div ng-app="myApp" ng-controller="myCtrl">
<select ng-init="selectedName = names[0]" ng-model="selectedName" ng-options="x for x in names">
</select>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.names = ["Google", "Runoob", "Taobao"];
});
</script>

ng-options 与 ng-repeat

  • 可以使用ng-repeat 指令来创建下拉列表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div ng-app="myApp" ng-controller="myCtrl">
<p>选择网站:</p>
<select ng-model="selectedSite">
<option ng-repeat="x in sites" value="{{x.url}}">{{x.site}}</option>
</select>
<h1>你选择的是: {{selectedSite}}</h1>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.sites = [
{site : "Google", url : "http://www.google.com"},
{site : "Runoob", url : "http://www.runoob.com"},
{site : "Taobao", url : "http://www.taobao.com"}
];
});
</script>
  • 使用 ng-options 指令,选择的值是一个对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div ng-app="myApp" ng-controller="myCtrl">
<p>选择网站:</p>
<select ng-model="selectedSite" ng-options="x.site for x in sites">
</select>
<h1>你选择的是: {{selectedSite.site}}</h1>
<p>网址为: {{selectedSite.url}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.sites = [
{site : "Google", url : "http://www.google.com"},
{site : "Runoob", url : "http://www.runoob.com"},
{site : "Taobao", url : "http://www.taobao.com"}
];
});
</script>

数据源为对象

  • 前面实例我们使用了数组作为数据源,以下我们将数据对象作为数据源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div ng-app="myApp" ng-controller="myCtrl">
<p>选择的网站是:</p>
<select ng-model="selectedSite" ng-options="x for (x, y) in sites">
</select>
<h1>你选择的值是: {{selectedSite}}</h1>
</div>
<p>该实例演示了使用对象作为创建下拉列表。</p>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.sites = {
site01 : "Google",
site02 : "Runoob",
site03 : "Taobao"
};
});
</script>
  • value 在 key-value 对中也可以是个对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div ng-app="myApp" ng-controller="myCtrl">
<p>选择一辆车:</p>
<select ng-model="selectedCar" ng-options="x for (x, y) in cars">
</select>
<h1>你选择的是: {{selectedCar.brand}}</h1>
<h2>模型: {{selectedCar.model}}</h2>
<h3>颜色: {{selectedCar.color}}</h3>
<p>注意选中的值是一个对象。</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.cars = {
car01 : {brand : "Ford", model : "Mustang", color : "red"},
car02 : {brand : "Fiat", model : "500", color : "white"},
car03 : {brand : "Volvo", model : "XC90", color : "black"}
}
});
</script>
  • 在下拉菜单也可以不使用 key-value 对中的 key , 直接使用对象的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div ng-app="myApp" ng-controller="myCtrl">
<p>选择一辆车:</p>
<select ng-model="selectedCar" ng-options="y.brand for (x, y) in cars"></select>
<p>你选择的是: {{selectedCar.brand}}</p>
<p>型号为: {{selectedCar.model}}</p>
<p>颜色为: {{selectedCar.color}}</p>
<p>下拉列表中的选项也可以是对象的属性。</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.cars = {
car01 : {brand : "Ford", model : "Mustang", color : "red"},
car02 : {brand : "Fiat", model : "500", color : "white"},
car03 : {brand : "Volvo", model : "XC90", color : "black"}
}
});
</script>

AngularJS 表格

  • ng-repeat 指令可以完美的显示表格
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("/try/angularjs/data/Customers_JSON.php")
.then(function (result) {
$scope.names = result.data.records;
});
});
</script>

废弃声明 (v1.5)

  • v1.5 中$http 的 success 和 error 方法已废弃。使用 then 方法替代
1
2
3
4
5
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("/try/angularjs/data/Customers_JSON.php")
.success(function (response) {$scope.names = response.records;});
});

使用 orderBy 过滤器

  • 排序显示,可以使用 orderBy 过滤器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names | orderBy : 'Country'">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("/try/angularjs/data/Customers_JSON.php")
.then(function (result) {
$scope.names = result.data.records;
});
});
</script>

显示序号 ($index)

  • 表格显示序号可以在 中添加 $index
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ $index + 1 }}</td>
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("/try/angularjs/data/Customers_JSON.php")
.then(function (result) {
$scope.names = result.data.records;
});
});
</script>

使用 $even 和 $odd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td ng-if="$odd" style="background-color:#f1f1f1">
{{ x.Name }}</td>
<td ng-if="$even">
{{ x.Name }}</td>
<td ng-if="$odd" style="background-color:#f1f1f1">
{{ x.Country }}</td>
<td ng-if="$even">
{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("/try/angularjs/data/Customers_JSON.php")
.then(function (result) {
$scope.names = result.data.records;
});
});
</script>

AngularJS SQL

  • 在前面章节中的代码也可以用于读取数据库中的数据

使用 PHP 从 MySQL 中获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.runoob.com/try/angularjs/data/Customers_MySQL.php")
.success(function (response) {$scope.names = response.records;});
});
</script>

ASP.NET 中执行 SQL 获取数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ x.Name }}</td>
<td>{{ x.Country }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://www.runoob.com/try/angularjs/data/Customers_SQL.aspx")
.success(function (response) {$scope.names = response.records;});
});
</script>

服务端代码

  • 使用 PHP 和 MySQL。返回 JSON。
  • 使用 PHP 和 MS Access。返回 JSON。
  • 使用 ASP.NET, VB, 及 MS Access。 返回 JSON。
  • 使用 ASP.NET, Razor, 及 SQL Lite。 返回 JSON

跨域 HTTP 请求

  • header(“Access-Control-Allow-Origin: *”);

PHP 和 MySql 代码实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
$conn = new mysqli("myServer", "myUser", "myPassword", "Northwind");
$result = $conn->query("SELECT CompanyName, City, Country FROM Customers");
$outp = "";
while($rs = $result->fetch_array(MYSQLI_ASSOC)) {
if ($outp != "") {$outp .= ",";}
$outp .= '{"Name":"' . $rs["CompanyName"] . '",';
$outp .= '"City":"' . $rs["City"] . '",';
$outp .= '"Country":"'. $rs["Country"] . '"}';
}
$outp ='{"records":['.$outp.']}';
$conn->close();
echo($outp);
?>

PHP 和 MS Access 代码实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=ISO-8859-1");
$conn = new COM("ADODB.Connection");
$conn->open("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=Northwind.mdb");
$rs = $conn->execute("SELECT CompanyName, City, Country FROM Customers");
$outp = "";
while (!$rs->EOF) {
if ($outp != "") {$outp .= ",";}
$outp .= '{"Name":"' . $rs["CompanyName"] . '",';
$outp .= '"City":"' . $rs["City"] . '",';
$outp .= '"Country":"'. $rs["Country"] . '"}';
$rs->MoveNext();
}
$outp ='{"records":['.$outp.']}';
$conn->close();
echo ($outp);
?>

ASP.NET, VB 和 MS Access 代码实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<%@ Import Namespace="System.IO"%>
<%@ Import Namespace="System.Data"%>
<%@ Import Namespace="System.Data.OleDb"%>
<%
Response.AppendHeader("Access-Control-Allow-Origin", "*")
Response.AppendHeader("Content-type", "application/json")
Dim conn As OleDbConnection
Dim objAdapter As OleDbDataAdapter
Dim objTable As DataTable
Dim objRow As DataRow
Dim objDataSet As New DataSet()
Dim outp
Dim c
conn = New OledbConnection("Provider=Microsoft.Jet.OLEDB.4.0;data source=Northwind.mdb")
objAdapter = New OledbDataAdapter("SELECT CompanyName, City, Country FROM Customers", conn)
objAdapter.Fill(objDataSet, "myTable")
objTable=objDataSet.Tables("myTable")
outp = ""
c = chr(34)
for each x in objTable.Rows
if outp <> "" then outp = outp & ","
outp = outp & "{" & c & "Name" & c & ":" & c & x("CompanyName") & c & ","
outp = outp & c & "City" & c & ":" & c & x("City") & c & ","
outp = outp & c & "Country" & c & ":" & c & x("Country") & c & "}"
next
outp ="{" & c & "records" & c & ":[" & outp & "]}"
response.write(outp)
conn.close
%>

ASP.NET, VB Razor 和 SQL Lite 代码实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@{
Response.AppendHeader("Access-Control-Allow-Origin", "*")
Response.AppendHeader("Content-type", "application/json")
var db = Database.Open("Northwind");
var query = db.Query("SELECT CompanyName, City, Country FROM Customers");
var outp =""
var c = chr(34)
}
@foreach(var row in query)
{
if outp <> "" then outp = outp + ","
outp = outp + "{" + c + "Name" + c + ":" + c + @row.CompanyName + c + ","
outp = outp + c + "City" + c + ":" + c + @row.City + c + ","
outp = outp + c + "Country" + c + ":" + c + @row.Country + c + "}"
}
outp ="{" + c + "records" + c + ":[" + outp + "]}"
@outp

AngularJS HTML DOM

  • AngularJS 为 HTML DOM 元素的属性提供了绑定应用数据的指令

ng-disabled 指令

  • ng-disabled 指令直接绑定应用程序数据到 HTML 的 disabled 属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div ng-app="" ng-init="mySwitch=true">
<p>
<button ng-disabled="mySwitch">点我!</button>
</p>
<p>
<input type="checkbox" ng-model="mySwitch">按钮
</p>
<p>
{{ mySwitch }}
</p>
</div>

ng-show 指令

  • ng-show 指令隐藏或显示一个 HTML 元素
1
2
3
4
5
6
7
<div ng-app="">
<p ng-show="true">我是可见的。</p>
<p ng-show="false">我是不可见的。</p>
</div>

ng-hide 指令

  • ng-hide 指令用于隐藏或显示 HTML 元素
1
2
3
4
5
6
7
<div ng-app="">
<p ng-hide="true">我是不可见的。</p>
<p ng-hide="false">我是可见的。</p>
</div>

AngularJS 事件

  • AngularJS 有自己的 HTML 事件指令

ng-click 指令

  • ng-click 指令定义了 AngularJS 点击事件
1
2
3
4
5
6
7
8
9
10
11
12
13
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="count = count + 1">点我!</button>
<p>{{ count }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count = 0;
});
</script>

隐藏 HTML 元素

  • ng-hide 指令用于设置应用部分是否可见
  • ng-hide=”true” 设置 HTML 元素不可见
  • ng-hide=”false” 设置 HTML 元素可见
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<div ng-app="myApp" ng-controller="personCtrl">
<button ng-click="toggle()">隐藏/显示</button>
<p ng-hide="myVar">
名: <input type=text ng-model="firstName"><br>
姓: <input type=text ng-model="lastName"><br><br>
姓名: {{firstName + " " + lastName}}
</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$scope.myVar = false;
$scope.toggle = function() {
$scope.myVar = !$scope.myVar;
}
});
</script>

显示 HTML 元素

  • ng-show 指令可用于设置应用中的一部分是否可见
  • ng-show=”false” 可以设置 HTML 元素 不可见
  • ng-show=”true” 可以以设置 HTML 元素可见
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div ng-app="myApp" ng-controller="personCtrl">
<button ng-click="toggle()">隐藏/显示</button>
<p ng-show="myVar">
名: <input type="text" ng-model="firstName"><br>
姓: <input type="text" ng-model="lastName"><br>
<br>
姓名: {{firstName + " " + lastName}}
</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('personCtrl', function($scope) {
$scope.firstName = "John",
$scope.lastName = "Doe"
$scope.myVar = true;
$scope.toggle = function() {
$scope.myVar = !$scope.myVar;
}
});
</script>

AngularJS 模块

  • 模块定义了一个应用程序
1
2
3
4
5
6
7
<div ng-app="myApp">...</div>
<script>
var app = angular.module("myApp", []);
</script>

添加控制器

  • 使用 ng-controller 指令来添加应用的控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>

添加指令

  • AngularJS 提供了很多内置的指令,你可以使用它们来为你的应用添加功能
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-app="myApp" runoob-directive></div>
<script>
var app = angular.module("myApp", []);
app.directive("runoobDirective", function() {
return {
template : "我在指令构造器中创建!"
};
});
</script>

模块和控制器包含在 JS 文件中

  • 通常 AngularJS 应用程序将模块和控制器包含在 JavaScript 文件中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>
<script src="myApp.js"></script>
<script src="myCtrl.js"></script>
</body>
</html>

函数会影响到全局命名空间

  • AngularJS 模块让所有函数的作用域在该模块下,避免了该问题

什么时候载入库

  • AngularJS 在 元素中被加载,因为对 angular.module 的调用只能在库加载完成后才能进行
  • AngularJS 库是在文档的 区域被加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
{{ firstName + " " + lastName }}
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
</body>
</html>

AngularJS 表单

  • AngularJS 表单是输入控件的集合

HTML 控件

  • input 元素
  • select 元素
  • button 元素
  • textarea 元素

数据绑定

  • Input 控件使用 ng-model 指令来实现数据绑定
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-app="myApp" ng-controller="formCtrl">
<form>
First Name: <input type="text" ng-model="firstname">
</form>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.firstname = "John";
});
</script>

Checkbox(复选框)

  • checkbox 的值为 true 或 false,可以使用 ng-model 指令绑定
1
2
3
4
5
6
7
<div ng-app="">
<form>
选中复选框,显示标题:
<input type="checkbox" ng-model="myVar">
</form>
<h1 ng-show="myVar">My Header</h1>
</div>

单选框

  • 单选框使用同一个 ng-model ,可以有不同的值,但只有被选中的单选按钮的值会被使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body ng-app="">
<form>
选择一个选项:
<input type="radio" ng-model="myVar" value="dogs">Dogs
<input type="radio" ng-model="myVar" value="tuts">Tutorials
<input type="radio" ng-model="myVar" value="cars">Cars
</form>
<div ng-switch="myVar">
<div ng-switch-when="dogs">
<h1>Dogs</h1>
<p>Welcome to a world of dogs.</p>
</div>
<div ng-switch-when="tuts">
<h1>Tutorials</h1>
<p>Learn from examples.</p>
</div>
<div ng-switch-when="cars">
<h1>Cars</h1>
<p>Read about cars.</p>
</div>
</div>

下拉菜单

  • ng-model 属性的值为你在下拉菜单选中的选项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<body ng-app="">
<form>
选择一个选项:
<select ng-model="myVar">
<option value="">
<option value="dogs">Dogs
<option value="tuts">Tutorials
<option value="cars">Cars
</select>
</form>
<div ng-switch="myVar">
<div ng-switch-when="dogs">
<h1>Dogs</h1>
<p>Welcome to a world of dogs.</p>
</div>
<div ng-switch-when="tuts">
<h1>Tutorials</h1>
<p>Learn from examples.</p>
</div>
<div ng-switch-when="cars">
<h1>Cars</h1>
<p>Read about cars.</p>
</div>
</div>

AngularJS 表单实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<body>
<div ng-app="myApp" ng-controller="formCtrl">
<form novalidate>
First Name:<br>
<input type="text" ng-model="user.firstName"><br>
Last Name:<br>
<input type="text" ng-model="user.lastName">
<br><br>
<button ng-click="reset()">RESET</button>
</form>
<p>form = {{user}}</p>
<p>master = {{master}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
$scope.master = {firstName: "John", lastName: "Doe"};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
});
</script>

AngularJS 输入验证

  • AngularJS 表单和控件可以验证输入的数据

输入验证

  • AngularJS 表单和控件可以提供验证功能,并对用户输入的非法数据进行警告
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<h2>验证实例</h2>
<form ng-app="myApp" ng-controller="validateCtrl"
name="myForm" novalidate>
<p>用户名:<br>
<input type="text" name="user" ng-model="user" required>
<span style="color:red" ng-show="myForm.user.$dirty && myForm.user.$invalid">
<span ng-show="myForm.user.$error.required">用户名是必须的。</span>
</span>
</p>
<p>邮箱:<br>
<input type="email" name="email" ng-model="email" required>
<span style="color:red" ng-show="myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">邮箱是必须的。</span>
<span ng-show="myForm.email.$error.email">非法的邮箱地址。</span>
</span>
</p>
<p>
<input type="submit"
ng-disabled="myForm.user.$dirty && myForm.user.$invalid ||
myForm.email.$dirty && myForm.email.$invalid">
</p>
</form>
<script>
var app = angular.module('myApp', []);
app.controller('validateCtrl', function($scope) {
$scope.user = 'John Doe';
$scope.email = 'john.doe@gmail.com';
});
</script>

AngularJS API

  • API 意为 Application Programming Interface(应用程序编程接口)

AngularJS 全局 API

  • AngularJS 全局 API 用于执行常见任务的 JavaScript 函数集合
  • 比较对象
  • 迭代对象
  • 转换对象

angular.lowercase()

  • 转换字符串为小写
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.x1 = "JOHN";
$scope.x2 = angular.lowercase($scope.x1);
});
</script>

angular.uppercase()

  • 转换字符串为大写
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.x1 = "John";
$scope.x2 = angular.uppercase($scope.x1);
});
</script>

angular.isString()

  • 判断给定的对象是否为字符串,如果是返回 true
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.x1 = "JOHN";
$scope.x2 = angular.isString($scope.x1);
});
</script>

angular.isNumber()

  • 判断给定的对象是否为数字,如果是返回 true
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-app="myApp" ng-controller="myCtrl">
<p>{{ x1 }}</p>
<p>{{ x2 }}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.x1 = "JOHN";
$scope.x2 = angular.isNumber($scope.x1);
});
</script>

AngularJS Bootstrap

  • AngularJS 的首选样式表是 Twitter Bootstrap, Twitter Bootstrap 是目前最受欢迎的前端框架

Bootstrap

  • 元素中添加如下代码
1
2
3
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
// 站点在国内,建议使用百度静态资源库的Bootstrap
<link rel="stylesheet" href="//apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.min.css">

HTML 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<body ng-app="myApp" ng-controller="userCtrl">
<div class="container">
<h3>Users</h3>
<table class="table table-striped">
<thead><tr>
<th>Edit</th>
<th>First Name</th>
<th>Last Name</th>
</tr></thead>
<tbody><tr ng-repeat="user in users">
<td>
<button class="btn" ng-click="editUser(user.id)">
<span class="glyphicon glyphicon-pencil"></span>&nbsp;&nbsp;Edit
</button>
</td>
<td>{{ user.fName }}</td>
<td>{{ user.lName }}</td>
</tr></tbody>
</table>
<hr>
<button class="btn btn-success" ng-click="editUser('new')">
<span class="glyphicon glyphicon-user"></span> Create New User
</button>
<hr>
<h3 ng-show="edit">Create New User:</h3>
<h3 ng-hide="edit">Edit User:</h3>
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">First Name:</label>
<div class="col-sm-10">
<input type="text" ng-model="fName" ng-disabled="!edit" placeholder="First Name">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Last Name:</label>
<div class="col-sm-10">
<input type="text" ng-model="lName" ng-disabled="!edit" placeholder="Last Name">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Password:</label>
<div class="col-sm-10">
<input type="password" ng-model="passw1" placeholder="Password">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Repeat:</label>
<div class="col-sm-10">
<input type="password" ng-model="passw2" placeholder="Repeat Password">
</div>
</div>
</form>
<hr>
<button class="btn btn-success" ng-disabled="error || incomplete">
<span class="glyphicon glyphicon-save"></span> Save Changes
</button>
</div>
<script src = "myUsers.js"></script>
</body>
</html>

AngularJS Bootstrap

  • AngularJS 的首选样式表是 Twitter Bootstrap, Twitter Bootstrap 是目前最受欢迎的前端框架

Bootstrap

  • 元素中添加如下代码
1
2
3
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
// 站点在国内,建议使用百度静态资源库的Bootstrap
<link rel="stylesheet" href="//apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.min.css">

HTML 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="http://apps.bdimg.com/libs/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<body ng-app="myApp" ng-controller="userCtrl">
<div class="container">
<h3>Users</h3>
<table class="table table-striped">
<thead><tr>
<th>Edit</th>
<th>First Name</th>
<th>Last Name</th>
</tr></thead>
<tbody><tr ng-repeat="user in users">
<td>
<button class="btn" ng-click="editUser(user.id)">
<span class="glyphicon glyphicon-pencil"></span>&nbsp;&nbsp;Edit
</button>
</td>
<td>{{ user.fName }}</td>
<td>{{ user.lName }}</td>
</tr></tbody>
</table>
<hr>
<button class="btn btn-success" ng-click="editUser('new')">
<span class="glyphicon glyphicon-user"></span> Create New User
</button>
<hr>
<h3 ng-show="edit">Create New User:</h3>
<h3 ng-hide="edit">Edit User:</h3>
<form class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">First Name:</label>
<div class="col-sm-10">
<input type="text" ng-model="fName" ng-disabled="!edit" placeholder="First Name">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Last Name:</label>
<div class="col-sm-10">
<input type="text" ng-model="lName" ng-disabled="!edit" placeholder="Last Name">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Password:</label>
<div class="col-sm-10">
<input type="password" ng-model="passw1" placeholder="Password">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">Repeat:</label>
<div class="col-sm-10">
<input type="password" ng-model="passw2" placeholder="Repeat Password">
</div>
</div>
</form>
<hr>
<button class="btn btn-success" ng-disabled="error || incomplete">
<span class="glyphicon glyphicon-save"></span> Save Changes
</button>
</div>
<script src = "myUsers.js"></script>
</body>
</html>

JavaScript 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
angular.module('myApp', []).controller('userCtrl', function($scope) {
$scope.fName = '';
$scope.lName = '';
$scope.passw1 = '';
$scope.passw2 = '';
$scope.users = [
{id:1, fName:'Hege', lName:"Pege" },
{id:2, fName:'Kim', lName:"Pim" },
{id:3, fName:'Sal', lName:"Smith" },
{id:4, fName:'Jack', lName:"Jones" },
{id:5, fName:'John', lName:"Doe" },
{id:6, fName:'Peter',lName:"Pan" }
];
$scope.edit = true;
$scope.error = false;
$scope.incomplete = false;
$scope.editUser = function(id) {
if (id == 'new') {
$scope.edit = true;
$scope.incomplete = true;
$scope.fName = '';
$scope.lName = '';
} else {
$scope.edit = false;
$scope.fName = $scope.users[id-1].fName;
$scope.lName = $scope.users[id-1].lName;
}
};
$scope.$watch('passw1',function() {$scope.test();});
$scope.$watch('passw2',function() {$scope.test();});
$scope.$watch('fName', function() {$scope.test();});
$scope.$watch('lName', function() {$scope.test();});
$scope.test = function() {
if ($scope.passw1 !== $scope.passw2) {
$scope.error = true;
} else {
$scope.error = false;
}
$scope.incomplete = false;
if ($scope.edit && (!$scope.fName.length ||
!$scope.lName.length ||
!$scope.passw1.length || !$scope.passw2.length)) {
$scope.incomplete = true;
}
};
});

AngularJS 包含

  • 在 AngularJS 中,你可以在 HTML 中包含 HTML 文件

在 HTML 中包含 HTML 文件

  • 在 HTML 中,目前还不支持包含 HTML 文件的功能

服务端包含

  • 大多服务端脚本都支持包含文件功能 (SSI: Server Side Includes)
  • 使用 SSI, 你可在 HTML 中包含 HTML 文件,并发送到客户端浏览器
1
<?php require("navigation.php"); ?>

客户端包含

  • 通常我们使用 http 请求 (AJAX) 从服务端获取数据,返回的数据我们可以通过 使用 innerHTML 写入到 HTML 元素中

AngularJS 包含

  • 使用 AngularJS, 你可以使用 ng-include 指令来包含 HTML 内容
1
2
3
4
5
<body ng-app="">
<div ng-include="'runoob.htm'"></div>
</body>
  • runoob.htm 文件代码
1
2
<h1>菜鸟教程</h1>
<p>这是一个被包含的 HTML 页面,使用 ng-include 指令来实现!</p>

包含 AngularJS 代码

  • ng-include 指令除了可以包含 HTML 文件外,还可以包含 AngularJS 代码
1
2
3
4
5
6
7
8
9
10
11
12
<div ng-app="myApp" ng-controller="sitesCtrl">
<div ng-include="'sites.htm'"></div>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('sitesCtrl', function($scope, $http) {
$http.get("sites.php").then(function (response) {
$scope.names = response.data.records;
});
});
</script>
  • sites.htm 文件代码
1
2
3
4
5
6
<table>
<tr ng-repeat="x in names">
<td>{{ x.Name }}</td>
<td>{{ x.Url }}</td>
</tr>
</table>

跨域包含

  • 默认情况下, ng-include 指令不允许包含其他域名的文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<body ng-app="myApp">
<div ng-include="'http://c.runoob.com/runoobtest/angular_include.php'"></div>
<script>
var app = angular.module('myApp', [])
app.config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
'http://c.runoob.com/runoobtest/**'
]);
});
</script>
</body>
  • 还需要设置服务端允许跨域访问
1
2
3
4
5
6
<?php
// 允许所有域名可以访问
header('Access-Control-Allow-Origin:*');
echo '<b style="color:red">我是跨域的内容</b>';
?>

AngularJS 动画

  • AngularJS 提供了动画效果,可以配合 CSS 使用
  • AngularJS 使用动画需要引入 angular-animate.min.js 库
1
<script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular-animate.min.js"></script>
  • 还需在应用中使用模型 ngAnimate
1
<body ng-app="ngAnimate">
  • 动画是通过改变 HTML 元素产生的动态变化效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<style>
div {
transition: all linear 0.5s;
background-color: lightblue;
height: 100px;
width: 100%;
position: relative;
top: 0;
left: 0;
}
.ng-hide {
height: 0;
width: 0;
background-color: transparent;
top:-200px;
left: 200px;
}
</style>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular-animate.min.js"></script>
</head>
<body ng-app="ngAnimate">
<h1>隐藏 DIV: <input type="checkbox" ng-model="myCheck"></h1>
<div ng-hide="myCheck"></div>
</body>
  • 如果我们应用已经设置了应用名,可以把 ngAnimate 直接添加在模型中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<style>
div {
transition: all linear 0.5s;
background-color: lightblue;
height: 100px;
width: 100%;
position: relative;
top: 0;
left: 0;
}
.ng-hide {
height: 0;
width: 0;
background-color: transparent;
top:-200px;
left: 200px;
}
</style>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular-animate.min.js"></script>
</head>
<body ng-app="myApp">
<h1>隐藏 DIV: <input type="checkbox" ng-model="myCheck"></h1>
<div ng-hide="myCheck"></div>
<script>
var app = angular.module('myApp', ['ngAnimate']);
</script>

ngAnimate 做了什么

  • ngAnimate 模型可以添加或移除 class
  • ngAnimate 模型并不能使 HTML 元素产生动画,但是 ngAnimate 会监测事件,类似隐藏显示 HTML 元素 ,如果事件发生 ngAnimate 就会使用预定义的 class 来设置 HTML 元素的动画
  • AngularJS 添加/移除 class 的指令
  • ng-show
  • ng-hide
  • ng-class
  • ng-view
  • ng-include
  • ng-repeat
  • ng-if
  • ng-switch

使用 CSS 动画

  • CSS transition(过渡) 或 CSS 动画让 HTML 元素产生动画效果

CSS 过渡

  • CSS 过渡可以让我们平滑的将一个 CSS 属性值修改为另外一个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
div {
transition: all linear 0.5s;
background-color: lightblue;
height: 100px;
}
.ng-hide {
height: 0;
}
</style>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular-animate.min.js"></script>
</head>
<body ng-app="myApp">
<h1>隐藏 DIV: <input type="checkbox" ng-model="myCheck"></h1>
<div ng-hide="myCheck"></div>
<script>
var app = angular.module('myApp', ['ngAnimate']);
</script>

CSS 动画

  • CSS 动画允许你平滑的修改 CSS 属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<style>
@keyframes myChange {
from {
height: 100px;
} to {
height: 0;
}
}
div {
height: 100px;
background-color: lightblue;
}
div.ng-hide {
animation: 0.5s myChange;
}
</style>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular-animate.min.js"></script>
</head>
<body ng-app="ngAnimate">
隐藏 DIV: <input type="checkbox" ng-model="myCheck">
<div ng-hide="myCheck">
</div>

AngularJS 依赖注入

什么是依赖注入

  • 依赖注入(Dependency Injection,简称DI)是一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分

AngularJS 提供很好的依赖注入机制。以下5个核心组件用来作为依赖注入

  • value
  • factory
  • service
  • provider
  • constant

value

  • Value 是一个简单的 javascript 对象,用于向控制器传递值(配置阶段)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 定义一个模块
var mainApp = angular.module("mainApp", []);
// 创建 value 对象 "defaultInput" 并传递数据
mainApp.value("defaultInput", 5);
...
// 将 "defaultInput" 注入到控制器
mainApp.controller('CalcController', function($scope, CalcService, defaultInput) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
}
});

factory

  • factory 是一个函数用于返回值。在 service 和 controller 需要时创建
  • 通常我们使用 factory 函数来计算或返回值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 定义一个模块
var mainApp = angular.module("mainApp", []);
// 创建 factory "MathService" 用于两数的乘积 provides a method multiply to return multiplication of two numbers
mainApp.factory('MathService', function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b
}
return factory;
});
// 在 service 中注入 factory "MathService"
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
...

provider

  • AngularJS 中通过 provider 创建一个 service、factory等(配置阶段)
  • rovider 中提供了一个 factory 方法 get(),它用于返回 value/service/factory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 定义一个模块
var mainApp = angular.module("mainApp", []);
...
// 使用 provider 创建 service 定义一个方法用于计算两数乘积
mainApp.config(function($provide) {
$provide.provider('MathService', function() {
this.$get = function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
}
return factory;
};
});
});

constant

  • constant(常量)用来在配置阶段传递数值,注意这个常量在配置阶段是不可用的
1
mainApp.constant("configParam", "constant value");

实例

  • AngularJS 实例 - factory
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<h2>AngularJS 简单应用</h2>
<div ng-app = "mainApp" ng-controller = "CalcController">
<p>输入一个数字: <input type = "number" ng-model = "number" /></p>
<button ng-click = "square()">X<sup>2</sup></button>
<p>结果: {{result}}</p>
</div>
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
<script>
var mainApp = angular.module("mainApp", []);
mainApp.value("defaultInput", 5);
mainApp.factory('MathService', function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
}
return factory;
});
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
mainApp.controller('CalcController', function($scope, CalcService, defaultInput) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
}
});
</script>
  • AngularJS 实例 - provider
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<h2>AngularJS 简单应用</h2>
<div ng-app = "mainApp" ng-controller = "CalcController">
<p>输入一个数字: <input type = "number" ng-model = "number" /></p>
<button ng-click = "square()">X<sup>2</sup></button>
<p>结果: {{result}}</p>
</div>
<script src="http://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
<script>
var mainApp = angular.module("mainApp", []);
mainApp.config(function($provide) {
$provide.provider('MathService', function() {
this.$get = function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
}
return factory;
};
});
});
mainApp.value("defaultInput", 5);
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
mainApp.controller('CalcController', function($scope, CalcService, defaultInput) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
}
});
</script>

AngularJS 路由

  • AngularJS 路由允许我们通过不同的 URL 访问不同的内容
  • 通过 AngularJS 可以实现多视图的单页Web应用(single page web application,SPA)
  • 通常我们的URL形式为 http://runoob.com/first/page,但在单页Web应用中 AngularJS 通过 # + 标记 实现
1
2
3
http://runoob.com/#/first
http://runoob.com/#/second
http://runoob.com/#/third

实例

  • 在以上图形中,我们可以看到创建了两个 URL: /ShowOrders 和 /AddNewOrder。每个 URL 都有对应的视图和控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<html>
<head>
<meta charset="utf-8">
<title>AngularJS 路由实例 - 菜鸟教程</title>
</head>
<body ng-app='routingDemoApp'>
<h2>AngularJS 路由应用</h2>
<ul>
<li><a href="#/">首页</a></li>
<li><a href="#/computers">电脑</a></li>
<li><a href="#/printers">打印机</a></li>
<li><a href="#/blabla">其他</a></li>
</ul>
<div ng-view></div>
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="http://apps.bdimg.com/libs/angular-route/1.3.13/angular-route.js"></script>
<script>
angular.module('routingDemoApp',['ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/',{template:'这是首页页面'})
.when('/computers',{template:'这是电脑分类页面'})
.when('/printers',{template:'这是打印机页面'})
.otherwise({redirectTo:'/'});
}]);
</script>
</body>
</html>