1.浅谈非入侵式JavaScript
<div ng-click="doSomething()">...</div>这些指令和原来的事件处理器有以下不同之处:
在所有浏览器中具有相同的行为。Angular将会帮你屏蔽差异性。
不会在全局命名空间中进行操作。你所指定的表达式只能访问元素控制器作用域范围内的函数和数据。
2.列表、表格以及其他迭代型元素
ng-repeat可能是最有用的Angular指令了,它可以根据集合中的项目一次创建一组元素的多份拷贝。不管在什么地方,只要你想创建一组事物的列表,你就可以使用这条令。
js代码:
var students = [{name:'Mary Contrary', id:'1'},
{name:'Jack Sprat', id:'2'},
{name:'Jill Hill', id:'3'}];
function StudentListController($scope) {
$scope.students = students;
$scope.insertTom = function () {
$scope.students.splice(1, 0, {name:'Tom Thumb', id:'4'});
};
}
html代码:
<ul ng-controller='StudentListController'>
<li ng-repeat='student in students'>
<a href='/student/view/{{student.id}}'>{{student.name}}</a>
</li>
</ul>
<button ng-click="insertTom()">Insert</button>
ng-repeat指令可以通过$index返回当前引用的元素序号;还可以通过$first、$middle及$last,ng-repeat指令返回布尔值,告诉你当前元素是否是集合中的第一个元素、中间的某个元素,或者最后一个元素。
html代码:
<table ng-controller='AlbumController'>
<tr ng-repeat='track in album'>
<td>{{$index + 1}}</td>
<td>{{track.name}}</td>
<td>{{track.duration}}</td>
</tr>
</table>
js代码:
var album = [{name:'Southwest Serenade', duration: '2:34'},
{name:'Northern Light Waltz', duration: '3:21'},
{name:'Eastern Tango', duration: '17:45'}];
function AlbumController($scope) {
$scope.album = album;
}
3.隐藏和显示
这个例子将会使用ng-show和ng-hide。这两条指令的功能是等价的,但是运行效果正好相反,它们都可以根据你所传递的表达式来显示或者隐藏元素。
这两条指令的工作原理是:根据实际情况把元素的样式设置为display:block来显示元素;设置为display:none来隐藏元素。
4.CSS类和样式
Angular提供了ng-class和ng-style指令。这两个指令都可以接受一个表达式,表达式执行的结果可能是如下取值之一:
表示CSS类名的字符串,以空格分隔。
CSS类名数组。
CSS类名到布尔值的映射。
css代码:
.selected {
background-color: lightgreen;
}
在模板中,我们把ng-class设置为{selected: $index==selectedRow}。这样做的效果就是,当模型属性selectedRow的值等于ng-repeat中的$index时,selected样式就会被设置到那一行上。
js代码:
function RestaurantTableController($scope) {
$scope.directory = [{name:'The Handsome Heifer', cuisine:'BBQ'},
{name:'Green's Green Greens', cuisine:'Salads'},
{name:'House of Fine Fish', cuisine:'Seafood'}];
$scope.selectRestaurant = function(row) {
$scope.selectedRow = row;
};
}
html代码:
<table ng-controller='RestaurantTableController'>
<tr ng-repeat='restaurant in directory' ng-lick='selectRestaurant($index)'
ng-class='{selected: $index==selectedRow}'>
<td>{{restaurant.name}}</td>
<td>{{restaurant.cuisine}}</td>
</tr>
</table>
5.反思src和href属性
由于浏览器会优先使用并行的方式来加载图片和其他内容,所以Angular没有机会拦截到数据绑定请求。
这里应该使用ng-src指令,你的模板应该写成这样:
<img ng-src="/images/cats/{{favoriteCat}}">
类似地,对于<a>标签,应该使用ng-href指令:
<a ng-href="/shop/category={{numberOfBalloons}}">some text</a>
6.表达式
表达式是通过Angular内置的解析器执行的。在这款解析器中,你找不到循环结构(for、while等)、流程控制操作符(if-else、throw),以及修改数据的操作符(++、--)。当你需要这些类型的操作符时,请在你的控制器中执行或者通过指令执行。虽然在很多方面这里的表达式比JavaScript更严格,但是它们对undefined和null的容错性更好。如果遇到错误,模板只是简单地什么都不显示,而不会抛出一个NullPointerException错误。
7.区分ui和控制器的职责
在应用中控制器有三种职责:
1> 为应用中的模型设置初始状态。
2> 通过 $scope对象把数据模型和函数暴露给视图(UI模板)。
3> 监视模型其余部分的变化,并采取相应的动作。
为视图中的每一块功能区域创建一个控制器。
有两种主要的方法可以把控制器关联到DOM节点上,第一种是在模板中通过ng-controller属性来声明,另一种是通过路由把它绑定到一个动态加载的DOM模板片段上,这个模板叫做视图。
<div ng-controller="ParentController">
<div ng-controller="ChildController">...</div>
</div>
虽然我们把这种方式叫做控制器嵌套,但真实的嵌套发生在$scope对象上。通过内部的原型继承机制,父控制器对象上的$scope会被传递给内部嵌套控制器的$scope。具
体到上面例子就是,ChildController的$scope对象可以访问ParentController的$scope对象上的所有属性(和函数)。
8.利用$scope暴露模型数据
对于显式地创建$scope属性我们已经看到过很多例子了,例如$scope.count = 5。还可以间接地通过模板自身创建数据模型。你可以通过以下几种方式来实现这一点。
1>通过表达式。
<button ng-click='count=3'>Set count to three</button>
2>在表单输入项上使用ng-model。与表达式类似,ng-model上指定的模型参数同样工作在外层控制器内。唯一的不同点在于,这样会在表单项和指定的模型之间建立双向绑定关系。