问题 | 解决方案 |
---|---|
创建一个单向链接 | 在控制器上使用定义属性,并使用ng-bind或者ng-bind-template指定或者是内敛表达式({{}}) |
阻止AngularJS处理内联绑定表达式 | 使用ng-non-bindable指令 |
创建双向数据绑定 | 使用ng-modle指令 |
生成重复内容 | 使用ng-repeat指令 |
获得ng-repeat指令中当前对象的上下文 | 使用ng-repeat指令提供的内置变量,例如
|
重复多个顶层属性 | 使用ng-repeat-start 和 ng-repeat-end |
加载一个局部视图 | 使用ng-include指令 |
有条件的显示元素 | 使用ng-switch |
在AngularJS处理内容时隐藏内联模板表达式 | 使用ng-cloak指令 |
为什么使用指令?
指令暴露了AngularJS的核心功能,如事件处理、表单验证和模板。你可以使用自定义指令在视图中使用你的程序功能。
何时使用指令?
指令在AngualrJS程序中的各个部分都能得到使用
数据绑定指令
指令 | 描述 |
---|---|
ng-bind | 绑定html元素的innerText属性 |
ng-bind-html | 使用一个HTML元素的innerHTML属性创建数据绑定。浏览器将把内容解释为HTML,而不只是内容 |
ng-bind-template | 与ng-bind指令类似,但是允许在属性值中指定多个模板表达式 |
ng-model | 创建一个双向数据绑定 |
ng-non-bindable | 声明一块不会执行数据绑定的区域 |
使用指令:
或者
执行和禁止单向绑定
单向绑定:从数据模型中获取值并插入到HTML元素中,当绑定所关联的值在数据模型中发生变化时,HTML元素也会随之被更新。
<body> <div id="todoPanel" class="panel" ng-controller="defaultCtrl"> <h3 class="panel-header">To Do List</h3> <div>There are {{todos.length}} items. </div> <div> There are <span ng-bind="todos.length"></span>items. </div> <div ng-bind-template="First: {{todos[0].action}}. Second: {{todos[1].action}}"></div> <div ng-non-bindable> AngularJS uses {{and}} characters for templates. </div> </div> </body> </html> <script type="text/javascript" src="../js/angular.js"></script> <script type="text/javascript"> angular.module("exampleApp",[]) .controller("defaultCtrl",function($scope){ $scope.todos = [ {action: "Get groceries",complete: false},{action: "Call plumber",{action: "Buy flowers",{action: "Call family",complete: true},{action: "Get groceries",complete: false} ]; }) </script>
{{}}内联绑定的缺点是AngularJS会寻找并处理内容中的每一对{{和}}括号。这可能成为问题。比如我们希望文本中显示{{和}}。解决方案是使用ng-non-bindable指令.
在请求绑定到一个不存在的模型属性时,AngularJS不会报错,因为它假设这个属性将会在之后创建,因此,它不会插入任何内容。
创建双向数据绑定
双向数据绑定会从两个方向同时跟踪变化,允许元素从用户处收集数据以修改程序的状态。双向数据绑定通过ng-model指令创建。
<body> <div id="todoPanel" class="panel" ng-controller="defaultCtrl"> <h3 class="panel-header">To Do List</h3> <div class="well"> <div>The first item is : {{todos[0].action}}</div> </div> <div class="form-group well"> <label>Set First Item:</label> <input type="text" class="form-control" ng-model="todos[0].action" /> </div> </div> </body>
双向绑定仅能应用于允许用户输入数据值的元素上,即:input、textarea和select元素.ng-model指令对所应用到的元素的内容进行设置,通过更新数据模型的方法响应用户所做的修改。
注:双向绑定的内在机制,当input元素的内容被修改时,AngularJS使用标准JavaScript事件从input元素接收通知,并且将这一变化通过$scope服务进行传播。
使用指令模板
AngularJS包含了一组可使用模板生成HTML元素的指令,使得使用数据集合进行工作,以及响应数据状态的模板中添加基本逻辑变得更为简单。
指令 | 描述 |
---|---|
ng-cloak | 使用一个CSS样式隐藏内联绑定表达式,在文档第一次加载时会短暂可见 |
ng-include | 在DOM中加载、处理和插入一段HTML |
ng-repeat | 对数组中或对象属性中的每个对象生成一个元素及其内容的若干新拷贝 |
ng-repeat-start | 表示含有多个顶层元素的重复区域的开始部分 |
ng-repeat-end | 表示含有多个顶层元素的重复区域的结束部分 |
ng-switch | 根据数据绑定的值修改DOM中的元素 |
重复生成元素
<tbody> <tr ng-repeat="item in todos"> <td>{{item.action}}</td> <td>{{item.complete}}</td> </tr> </tbody>
ng-repeat的基本形式: in,其中source是控制器$scope所定义的一个对象或数组。
ng-repeat可以嵌套使用,上述的代码还可以写成下面形式:
<tbody> <tr ng-repeat="item in todos"> <td ng-repeat="prop in item">{{prop}}</td> </tr> </tbody>
使用数据对象的键值进行工作
<tbody> <tr ng-repeat="item in todos"> <td ng-repeat="(key,value ) in item">{{key}} : {{value}}</td> </tr> </tbody>
使用内置变量
变量 | 描述 |
---|---|
$index | 返回当前对象或属性的位置 |
$first | 在当前对象为集合中的第一个对象时返回true |
$middle | 在当前对象既不是集合的第一个对象也不是集合的最后一个对象时,返回true |
$last | 在当前对象为集合中的最后一个对象时返回true |
$even | 对于集合中偶数编号的对象时返回true |
$odd | 对于集合中奇数编号的对象时返回true |
<body> <div id="todoPanel" class="panel" ng-controller="defaultCtrl"> <h3 class="panel-header">To Do List</h3> <table class="table"> <thead> <tr> <th>Action</th> <th>Done</th> </tr> <tbody> <tr ng-repeat="item in todos"> <td>{{$index + 1}}</td> <td ng-repeat="prop in item">{{prop}}</td> </tr> </tbody> </thead> </table> </div> </body> </html> <script type="text/javascript" src="../js/angular.js"></script> <script type="text/javascript"> angular.module("exampleApp",complete: true} ]; }); </script>
效果如下所示:
$index是从0开始的。
<style type="text/css"> .odd{background: green;} .even{background: pink;} </style>
<tbody> <tr ng-repeat="item in todos" ng-class="$odd ? 'odd' : 'even' "> <td>{{$index + 1}}</td> <td ng-repeat="prop in item">{{prop}}</td> </tr> </tbody>
<tbody> <tr ng-repeat="item in todos" ng-class="$odd ? 'odd' : 'even' "> <td>{{$index + 1}}</td> <td>{{item.action}}</td> <td><span ng-if="$first || $last">{{item.complete}}</span></td> </tr> </tbody>
当是集合中的第一个和最后一个元素时,才会显示complete属性值
重复生成多个顶层元素
使用ng-repeat-start和ng-repeat-end对每个数据对象重复生成多个顶层元素。
<tbody> <tr ng-repeat-start="item in todos" ng-class="$odd ? 'odd' : 'even' "> <td>This is item {{$index}}</td> </tr> <tr> <td>The action is: {{item.action}}</td> </tr> <tr ng-repeat-end> <td Item {{$index}} is {{$item.complete ? "" : "not"}}> item.complete</span></td> </tr> </tbody>
效果如下所示:
对每个对象生成了3个tr元素
使用局部视图
ng-include指令从服务器获取一段HTML片段,编译并处理其中包含的任何指令,并添加到DOM中去,这些片段被称为局部视图。
新建一个table.html,将table存在里面。
<table class="table"> <thead> <tr> <th>Action</th> <th>Done</th> </tr> <tbody> <tr ng-repeat="item in todos" ng-class="$odd ? 'odd' : 'even' "> <td>{{$index + 1}}</td> <td>{{item.action}}</td> <td>{{item.complete}}</td> </tr> </tbody> </thead> </table>
在原html中使用ng-include引入,注意,ng-include一定要使用闭合标签,即
<div id="todoPanel" class="panel" ng-controller="defaultCtrl">
<h3 class="panel-header">To Do List</h3>
<ng-include src=" 'table.html' "></ng-include>
</div>
遇到ng-include指令,AngularJS会自动发出一个Ajax请求获得table.html文件,处理文件内容并添加到文档中。
ng-include除了src外,还有两个参数:
名称 | 描述 |
---|---|
src | 指定要加载的内容的URL |
onload | 指定一个在内容被加载时调用计算的表达式 |
autoscroll | 指定在内容被加载时,angualrJS是否应该滚动到这部分视图所在的区域 |
利用ng-include指令可以将一个视图拆分为多个局部视图,可以创建可复用的局部视图,并被整个应用程序所使用,可避免数据重复并保证数据表达形式的一致性。
==注意src中的写法。==
src属性中是一个字符串变量,’table.html’,这是因为src属性是被当作JS表达式进行计
算的,要静态的定义一个文件,就需要使用单引号将文件名包含起来。
ng-include的真正威力在于src的设置是可以通过计算得到。
<body ng-controller="defaultCtrl">
<div id="todoPanel" class="panel" >
<h3 class="panel-header">To Do List</h3>
</div>
<div class="well">
<div class="checkBox">
<label>
<input type="checkBox" ng-model="showList">Use the list view
</label>
</div>
<ng-include src="viewFile()"></ng-include>
</div>
</body>
</html>
<script type="text/javascript"> angular.module("exampleApp",complete: true} ]; $scope.viewFile = function(){ return $scope.showList ? "list.html" : "table.html"; } }); </script>
新建一个list.html.根据是否选中checkBox来显示不同的视图。
ng-switch指令
<body ng-controller="defaultCtrl"> <div id="todoPanel" class="panel" > <h3 class="panel-header">To Do List</h3> </div> <div class="well"> <div class="radio" ng-repeat="button in ['None','Table','List']"> <label> <input type="radio" ng-model="data.mode" value="{{button}}" ng-checked="$first"> {{button}} </label> </div> </div> <div ng-switch on="data.mode"> <div ng-switch-when="Table"> <table class="table"> <thead> <tr> <th>#</th> <th>Action</th> <th>Done</th> </tr> </thead> <tr ng-repeat="item in todos"> <td>{{$index + 1}}</td> <td>{{item.action}}</td> <td>{{item.complete}}</td> </tr> </table> </div> <div ng-switch-when="List"> <ol> <li ng-repeat="item in todos"> {{item.action}} <span ng-if="item.complete"> (Done)</span> </li> </ol> </div> <div ng-switch-default> Select another option to display a layout </div> </div> </body> </html> <script type="text/javascript"> angular.module("exampleApp",function($scope){ $scope.data={}; $scope.todos = [ {action: "Get groceries",complete: true} ]; $scope.viewFile = function(){ return $scope.showList ? "list.html" : "table.html"; }; }); </script>
ng-switch指令中使用on属性指令一个表达式,用于计算并决定那部分内容将被显示。。
隐藏未处理的内联模板绑定表示式
使用内联绑定,有时会看到{{}},为了不让用户看到,我们可以使用ng-bind或者使用ng-cloak.对需要的地方指定。
如:
<div ng-switch-when="List"> <ol> <li ng-repeat="item in todos" ng-cloak> {{item.action}} <span ng-if="item.complete"> (Done)</span> </li> </ol> </div>