《学习笔记》在AngularJS视图中实现指令

    AngularJS最强大的功能之一是指令。指令扩展了HTML的行为,使你可以创建自定义的HTML元素,属性和特定于应用程序的类与功能。AngularJS提供了一些内置的指令。事实上,AngularJS库的主要部分就是内置的指令。这些指令提供了与表单元素进行交互,把作用域内的数据绑定到视图,并与浏览器事件交互的能力。

    下面讨论内置的指令,以及如何在AngularJS模板中实现它们。在后面,你还将学习如何建立自己的自定义指令。

1,了解指令

    指令是AngularJS模板标记和用于支持的JavaScript代码的组合。AngularJS指令标记可以是HTML属性,元素名称或CSS类。JavaScript的指令代码定义了模板数据以及HTML元素的行为。

    AngualrJS编译器遍历DOM的模板并编译所有指令。然后,它通过将指令与作用域结合,以产生一个新的实时视图来链接指令。实时视图包含在指令中定义的DOM元素和功能。

2,使用内置指令

    你需要在HTML元素中实现的大多数AngularJS功能都有内置的指令提供。这些指令由库提供,并在AngularJS JavaScript库被加载时可用。

    指令对AngularJS应用程序提供各种各样的支持,以下将描述大部分AngularJS指令,它们大致分为以下几类:

  • 主持AngualarJS功能的指令
  • 扩展表单元素的指令
  • 把作用域绑定到页面元素的指令。
  • 把网页事件绑定到控制器的指令
2.1,支持AngularJS功能的指令

    有多个指令用于对angularJS功能的支持。这些指令执行初始化一个应用程序的一切功能,以确保AngularJS所需要的不二表达式被保留在DOM中

    下表列出了这些指令,并描述了它们各自的行为和用法。

支持AngularJS模板功能的指令
指令 说明
ngApp

这个指令用于把应用程序初始化到根元素。这个属性被设定为作为应用程序根使用的AngularJS模块名称,以及把

它作为该模板的编译根来包含的HTML元素。例如,下面的代码把模块myApp设置为<html>元素中的应用程序:

<html gn-app="myApp">

ngcloak 当一个元素中存在此属性时,只有AngularJS模板已经完全编译,才会显示该元素。否则,显示元素的原始形式和模板代码
ngController

这个指令在视图中对该元素附加一个控制器,以创建一个新的作用域,如前面章节所述。例如:

<div ng-controller="myController"></div>

ngHref

这是你可以用来代替使用href属性的一个选项,如果你包含类似{{hash}}的模板语法,那么如果用户在表达式求值前单击链接

,href属性可能是损坏的

ngInclude

这个指令自动获取,编译并包含来自服务器的外部HTML片段。使用它是一个很棒的方式来包含来自服务器端脚本的部

分HTML数据,例如:<div ng-include="/info/sidebar.html">

ngList

这个指令把作用域中的数组对装换为分隔符分隔的字符串(逗号是默认的分隔符)。例如,如果作用域包含名为items的数组

,在下面的<input>中所显示的值是item1,item2,...  <input ng-model="items" ng-list=",">

ngNonBindable

当一个元素中存在此指令时,AngularJS在编译时不便于或绑定元素的内容。如果你想在元素中显示代码,这是很有用的。

例如:<p ng-non-bindable>Expression Syntax:{{exp}}</p>

ngOpen 浏览器不要求保持元素的布尔属性。如果这个属性存在,那么它是true。该指令允许你通过测试属性的存在性来维护元素的true/false状态。例如,下面的例子基于在作用域的open值应用ngOpen:  <detailes ng-open="open">
ngPluralize

该指令允许你根据捆绑在AnularJS的en-US本地化规则显示信息。可以通过添加count和when属性来配置ngPluralize,如下所示:

<p ng-pluralize count="itemCount" 

    when="{'0':'Cart is empty.',

                'one':'Purchase 1 item.',

                'other':'Purchase{{itemCount}}items.'}">

</p>

ngReadonly

类似于ngOpen,但用于readonly布尔值。例如,下面的例子基于在作用域的notChageable值应用于ngReadonly:

<input type="text" ng-readonly="notChangeable">

ngRequired

这个指令类似于ngOpen,但用于required布尔值。例如,下面的例子基于在作用域的required值应用ngRequired:

<input type="text",ng-required="required">

ngSelected

这个指令类似于ngOpen,但用于selected布尔值。例如,下面的例子基于在作用域的selected值应用ngSelected:

<option id="optionA" ng-selected="selected">Option A</option>

ngSrc 你可以用此指令来代替使用src属性。如果你包含类似{{hash}}的模板语法,那么在表达式被求值前,src属性是损坏的
ngSrcset 你可以用辞职了来代替使用的srcset属性。在表达式求值前,srcset属性是损坏的。例如:<img ng-src="/images/{{hash}}/test.jpg 2x" />
ngTransclude 该指令把元素标志为转置点,供使用transclude选项来包装其他元素的指令使用

ngView

script

该指令把当前的已呈现的模板包含到主布局文件。

这个指令加载具有next/ng-template的脚本标记的内容,以便它可以被ngInclude,ngView或其他模板指令使用

2.2,扩展表单元素的指令

    AngularJS在很大程度上与表单元素整合,以对应用程序的表单元素提供数据绑定和事件绑定。为了以正确的方式提供AngularJS功能,表单元素在编译时被扩展。

    下表列出了AngularJS扩展的表单元素

扩展表单元素来支持AngularJS模板功能的指令
指令 说明
a

该指令修改默认行为,防止href属性为空时的默认操作。这使你可以利用ngClick或其他时间指令来创建操作链接。例如:

<a href="" ng-click="handleClick()">Click Me</a>

from/ngFrom

AngularJS允许处于验证目的而嵌套表单,这样一来,当一个表单的所有子表单都有效时,它也是有效的。然而浏览器不

允许<from>元素嵌套。因此,你应该使用<ng-from>来代替它。例如:

<ng-form name="myForm">

    <input type="text" ng-model="myName" required>

</ng-form>

input

你可以修改此指令来提供一下附加的AngularJS属性:

  • ngModel:把此输入的值绑定到该作用域的变量中
  • name:指定表单的名称
  • required:如果存在,则这个字段需要有值
  • ngRequired:根据ngRequired表达式求值的结果设置required属性
  • ngMinlength:设置minength验证错误数量
  • ngMaxlength:设置maxlength验证错误数量
  • ngPattern:指定一个正则表达式来匹配进行验证的输入值
  • ngChange:指定一个当输入改变时要执行的表达式(例如,执行在该作用域内的一个函数)
input.checkbox

该指令在那些input已经提供的属性基础上增加了以下额外的AngularJS属性

  • ngTrueValue:当元素被选中时,设定作用域内的一个值
  • ngFalseValue:当元素没有被选择是,设置模型中的一个值
input.email 这个指令与input相同
input.number

该指令在那些input已经提供的属性基础上增加了以下额外的AngualrJS属性

  • min:设置min验证错误数量
  • max:设置max验证错误数量
input.radio

该指令在那些input已经提供的属性基础上增加了以下额外的AngularJS属性

  • value:当元素被选中是,设定作用域内的一个值
input.text 这个指令与input相同
input.url 这个指令与input相同
select 该指令为<select>元素增加了额外的ngOptions指令
ngOptions

该指令允许你基于一个迭代表达式添加选项。如果在作用域内的数据源是一个数组,则用下面的表达式来为ngOptions设置<select>中的每个<option>元素的label,name和value属性:

label for value in array

select as label for value in array

label group by group for valur in array

select as label group by group for value in array track by trackexpr

如果在作用域内的ngOptions源是一个JavaScript对象,则请使用以下表达式语法:

label for (key,value) in object

select as label for(key,value) in object

label group by group for(key,value) in object

select as label group by group for(key,value) in obect

例如:

<select ng-model="color" ng-options="c.name for c in colors">

    <option value="">-- choose color --</option>

</select>

textarea 这个指令与input相同

    下面的代码清单实现了一些与作用域集成的基本AngularJS表单元素。

        directive_form.js:实现一个用于表单指令的控制器

angular.module('myApp',[]).
	controller('myController',function($scope){
		$scope.someText = '';
		$scope.cameras = [
		{make:'Nikon',model:'70D',mp:20.2},
		{make:'Canon',model:'6D',mp:20},
		{make:'Canon',model:'D7100',mp:24.1},
		{make:'Nikon',model:'D5200',mp:24.1}];
		$scope.cameraObj = $scope.cameras[0];
		$scope.cameraName = 'Canon';
		$scope.cbValue = '';
	});

                directive_form.html:实现几种不同的表单元素指令的AngularJS模板

<!doctype html>
<html ng-app="myApp">
<head>
	<title>First AngularJS APP</title>
</head>
<body ng-controller="myController">
	<h2>Froms Directives</h2>
	<input type="text" ng-model="someText">{{someText}}<hr>
	<input type="checkbox" ng-model="cbValue"
		ng-true-value="AWESOME" ng-false-value="BUMMER">
	checkbox:{{cbValue}}<br>
	<input type="radio" ng-model="cameraName" value="Canon">Canon<br/>
	<input type="radio" ng-model="cameraName" value="Nikon">Nikon<br/>
	SelectedCamera:{{cameraName}}<hr>
	<select ng-model="camera" ng-options="c.model group by c.make for c in cameras">
	</select>
	{{camera|json}}

<script src="js/angular.js"></script>
<script src="js/directive_form.js"></script>
</body>
</html>

2.3,把模型绑定到页面元素的指令

    AngularJS模板事你可以把在该作用域内的数据直接绑定到所显示的HTML元素。你可以用几种不同的方式把数据绑定到视图,如下所示。

  • 值:你可以直接表示在作用域中的表单元素的值。例如,文本输入可以是作用域中的String变量;而一个复选框,将通过一1给补而值来表示
  • HTML:你可以利用诸如下面的表达式来在一个元素的HTML输出中表示作用域数据的值:<p>{{myTitle}}<p>
  • 属性:HTML元素的属性的值可以利用诸如下面的表达式定义来反应在作用域中的数据:<a ng-href="/{{hash}}/index.html">{{hash}}</a>
  • 可见性:元素的可见性可以反映在视图的作用域中。例如,当基于该作用域的表达式为true时,则该元素是可见的;否则,它是不可见的。
  • 存在性:你可以根据在该作用域内的值省略已编译的DOM中的元素。

    下表列出了把作用域内的数据直接绑定到视图元素中的指令

把作用域内的数据绑定到HTML元素的值,表达式,可见性以及存在性的指令
指令 说明
ngBind

该指令告诉AngularJS用给定表达式的值来替换HTML元素的文本内容;并且如果在该作用域内的值发生变化,就

更新文本内容。例如:<span ng-bind="titleString"></span>

ngBindHtml

该指令告诉AngularJS用给定表达式的值来替换HTML元素的innerHTML内容;并且如果在该作用域内的值发生变

化,就更新innerHTML内容。例如:<div ng-bind="someHTML"></div>

ngBindTemplate

这个指令类似于ngBind,但表达式可以包含多个{{}}表达式块。例如:

<span ng-bind="{{aValue}} and {{anotherValue}}"></span>

ngClass

这个指令通过数据绑定表示要添加的类的表达式,动态设置元素的CSS类。当表达式的值发生变化时,该元素

的CSS类会自动被更新。例如:<p ng-class="myPStyles"><p>

ngClassEven

这个指令与ngClass是一样的,不同之处在于它使用ngRepeat来只对一个集合中索引为偶数的元素应用类的变化。例如:

<li ng-repeat="item in items">

    <span ng-class-odd="oddRowClass">{{item}}</span>

</li>

ngClassOdd 这个指令与ngClass是一样的,不同之处在于它使用ngRepeat来只对一个集合中索引为奇数的元素应用类的变化
ngDisabled 如果表达式的值为true,则这个指令禁用一个按钮元素
ngHide

这个指令基于提供的表达式,使用AngularJS提供的.ng-hide CSS类来显示或隐藏HTML元素。如果表达式在作用域

中求值为false,则显示该元素;否则,它是隐藏的。例如:<div ng-show="myValue"></div>

ngShow

这个指令与ngHide的作用是一样的,但意义刚好相反;如果表达式在作用域内的值为true,则显示该元素;否则,

它是隐藏的,例如:<div ng-show="myValue"></div>

ngIf

这个指令会基于表达式删除或重建创建DOM数的一部分。这与显示或隐藏不同,因为HTML根本不会显示在DOM中。

例如:<div ng-if="present"></div>

ngModel

该指令把<input><select>或<textarea>元素的值绑定到作用域模型的值中。当用户绑定该元素的值时,该值被自

动地在作用域改变;反之亦然:例如:<input type="text" ng-model="myString">

ngRepeat

该指令允许你基于该作用域内的数组添加多个HTML元素。这对列表,表格和菜单极为有用。ngRepeat使

用item in collections式的迭代语法。它为每个创建的HTML元素创建一个新的作用域。在循环中产生HTML元素的过程中,

下面的变量都在作用域的过程中可见

  • $index:基于第一个元素为0的迭代器的索引
  • $first:一个布尔值,如果这是第一个元素,则为true
  • $middle:一个布尔值,如果这不是第一个或最后一个元素,则为true
  • $last:一个布尔值,如果这是最后一个元素,则为true
  • $even:一个布尔值,如果迭代去是偶数,则为true
  • $odd:一个布尔值,如果迭代器是奇数,则为true
ngInit

这个指令与ngRepeat连用,在迭代过程中初始化一个值。例如:

<div ng-repeat="user in users" ng-init="offset=21">

    {{$index+offset}}:{{user.firstname}}</div>

ngStyle

该指令允许你根据作用域的一个属性名称和值与CSS属性匹配的对象动态地设置样式。例如:

<span ng-style="myStyle">Stylized Text</span>

ngSwitch

ngValue

该指令允许你根据一个作用域表达式动态的切换把哪个DOM元素包含在已编译的模板中。

该指令把选中的input[select]或input[radio]值绑定到ngModel指定的表达式中。

    下面的代码清单提供了一些基本AngularJS绑定指令的一些实例。

                directive_bind.js:用作用域模型实现控制器,以支持数据绑定指令

angular.module('myApp',[]).
	controller('myController',function($scope){
		$scope.colors=['red','green','blue'];
		$scope.myStyle = {"background-color":'blue'};
		$scope.days = ['Monday','Tuesday','Wednexday','Thursday','Friday'];
		$scope.msg = "Message from the model";
	});

                directive_bind.html:实现多个不同的数据绑定指令的AngularJS模板

<!doctype html>
<html ng-app="myApp">
<head>
	<style>
	.even{background-color:lightgrey;}
	.rect{display:inline-block;height:40px;width:100px;}
	</style>
</head>
<body>
	<div ng-controller="myController">
		<h2>Data Binding Directives</h2>
		<label ng-repeat="color in colors">
		{{color}}
		<input type="radio" ng-model="myStyle['background-color']" ng-value="color" id="{{color}}" name="nColor">
		</label>
		<span class="rect" ng-style="myStyle"></span><hr>
		<li ng-repeat="day in days">
			<span ng-class-even="'even'">{{day}}</span>
		</li><hr>
		Show Message:<input type="checkbox" ng-model="checked" />
		<p ng-if="checked" ng-bind="msg"></p>
	</div>

<script src="js/angular.js"></script>
<script src="js/directive_bind.js"></script>
</body>
</html>

2.4,把页面事件绑定到控制器的指令

    AngularJS模板可以吧浏览器事件绑定到控制器代码。这意味着你可以从作用域的角度处理用户输入。然后,你可以实现处理程序直接把浏览器事件绑定到合适的作用域。event指令的工作方式非常像普通的事件浏览器处理程序(除了它们被直接链接到作用域上下文外)。

    下表列出了把页面和设备事件绑定到AngularJS模式的指令。这些指令都允许你指定一个表达式,这通常是在作用域内定义的函数,

把网页/设备事件绑定到AngularJS模型功能的指令
指令 说明
ngBlur 模糊事件被触发时,该指令计算一个表达式的值
ngChange 表单元素的值发生变化时,该指令计算一个表达式的值
ngChecked 复选框或单选元素被选中时,该指令计算一个表达式的值
ngClick 单击鼠标时,该指令计算一个表达式的值
ngCopy 模糊复制被触发时,该指令计算一个表达式的值
ngCut 模糊剪切被发生时,该指令计算一个表达式的值
ngDblclick 双击鼠标时,该指令计算一个表达式的值
ngFocus 模糊焦点被触发时,该指令计算一个表达式的值
ngKeypress 键盘的键被按下时,该指令计算一个表达式的值
ngKeyup 键盘的键被释放时,该指令计算一个表达式的值
ngMousedown 鼠标键被按下时,该指令计算一个表达式的值
ngMouseenter 当鼠标进入某个元素时,该指令计算一个表达式的值
ngMouseleave 当鼠标离开某元素时,该指令计算一个表达式的值
ngMousemove 鼠标光标移动时
ngMouseover 当鼠标悬停在一个元素上时,该指令计算一个表达式的值
ngMouseup 释放鼠标按钮时
ngPaste 粘贴事件被触发时
ngSubmit 该指令阻止默认表单提交动作(即把请求发生到服务器),而用计算指令的表达式的值来代替它
ngSwipeLeft 向左滑动事件被触发时
ngSwipeRight 向右滑动事件被触发时
   

    你可以利用$event关键字把JavaScript Event对象传递到事件表达式。这时你可以访问有关该事件的信息,以及停止传播该事件和你通常可以对一个JavaScript Event对象做的任何是。例如,下面的ng-click指令把单击事件传递给没有Click()处理函数:

<input type="button" ng-click="myClick($event)">

    下面的代码清单提供了基本的AngularJS事件指令的一些实例。

                    directive_event.js:实现一个具有作用域数据和事件处理程序的控制器

angular.module('myApp',[]).
	controller('myController',function($scope){
		$scope.keyInfo = {};
		$scope.mouseInfo = {};
		$scope.keyStroke = function(event){
			$scope.keyInfo.keyCode = event.keyCode;
		};
		$scope.mouseClick = function(event){
			$scope.mouseInfo.clientX = event.clientX;
			$scope.mouseInfo.clientY = event.clientY;
			$scope.mouseInfo.screenX = event.screenX;
			$scope.mouseInfo.screenY = event.screenY;
		}
	});

                    directive_event.html:实现多个不同的事件指令的AngularJS模板

<!doctype html>
<html ng-app="myApp">
<head>
</head>
<body>
	<div ng-controller="myController">
		<h2>Event Directives</h2>
		<input type="text"
			ng-blur="focusState='Blurred'"
			ng-focus="focusState='Focused'"
			ng-mouseenter="mouseState='Entered'"
			ng-mouseleave="mouseState='Left'"
			ng-mouseclick="mouseState='Clicked'"
			ng-mousedown="mouseState='Down'"
			ng-mouseup="mouseState='Up'"
			ng-keyup="keyStroke($event)"
			ng-click="mouseClick($event)"><hr>
		Focus State:{{focusState}}<br/>
		Mouse State:{{mouseState}}<br/>
		Key Info:{{keyInfo|json}}<br/>
		Mouse Info:{{mouseInfo|json}}<br/>
	</div>

<script src="js/angular.js"></script>
<script src="js/directive_event.js"></script>
</body>
</html>

3,创建你自己的指令来扩展HTML

    与AngularJS的许多其他功能一样,你也可以通过创建自己的自定义指令来扩展指令的功能。自定义指令允许你通过自己实现元素的行为来扩展HTML的功能。如果你有需要操作DOM的代码,就应该利用自定义指令做到这一点。

    你可以通过在一个Module对象上调用direcitve()方法实现自定义指令。directive()方法接受一个指令名称作为第一个参数,并接受一个提供器函数来返回一个对象,这个对象包含必要的指令来构建指令对象。例如,下面是一个指令的基本定义:

angular.module('myApp',[]).
	directive('myDirective',function(){
		return{
			template:'Name:{{name}} Score:{{score}}'
			};
		};

    当模板在上面的代码中返回时,你可以把以下的属性列表应用于该指令定义返回的对象。

  • template:允许你定义插入指令的元素的AngualrJS模板文本
  • templateUrl:同template(除了你在服务器上指定一个URL,且局部模板被下载并被插入指定的元素中)
  • restrict:允许你指定该指令是应用于一个HTML元素,还是一个属性,或两者兼有之。
  • replace:告诉编译器,用指令的模板来取代定义该指令的元素
  • transclude:允许你指定指令是否可以访问内部作用域以外的作用域。
  • scope:允许你为指令指定内部作用域
  • link:允许你指定可以访问该作用域,DOM元素和其他能操作DOM属性的链接函数
  • controller:允许你在指令中实现一个控制器来管理该指令作用域和视图
  • require:允许你指定要实现这个指令所需要的其他指令。这些指令的提供器对于要创建的这个指令的实例必须是可用的。

   下面将详细讨论这些指令选项

3.1,定义指令视图模板

    你可以包含AngularJS模板代码来构建将显示在包含该指令的HTML元素的视图组件。你可以直接使用templae属性添加模板代码,如下面的例子所示:

directive('myDirective',function(){
		return{
			template:'Name:{{name}} Score:{{score}}'
			};
		};

    你可以在自定义模板中指定一个根元素,但只能有一个元素。这个元素作为要放置在它里面的AngualarJS模板中定义的所有子元素的根元素。另外,如果你使用的是transclude标志,则此元素应该包含ngTransclude。例如:

directive('myDirective',function(){
	return{
		transclude:true,
		template:'<div ng-transclude></div>'
		};
	});

    你也可以使用templateUrl属性来指定位于Web服务器的AngularJS模板的URL,如下面的例子所示:

derective('myDirective',function(){
	return{
		templateUrl:'/myDirective.html'
		};
	});

    该模板的URL可以包含任何标准的AngularJS模板代码。因此,你可以根据需要让指令任意简单和复杂。

3.2,限制指令行为

    你可以将指令应用为一个HTML元素,一个属性,或两者兼有之。restrict属性允许你限制你的自定义指令可以如何被应用。restrict属性可以被设置为下面这样。

  • A:应用为一个属性名
  • E:应用为一个元素名
  • C:应用为一个类名
  • AEC:应用为一个属性名,一个元素名,或者一个类名。你也可以使用其他组合,如AE或AC。

    例如,你可以将以下指令应用为一个属性或一个元素:

directive('myDirective',function(){
	return{
		restrict:'AE',
		templateUrl:'/myDirective.html'
		}
	});

    下面显示了如何把指令即实现为一个元素又实现为一个属性。请注意,驼峰名称被替换为一个包含连字符的名称:

<my-directive></my-directive>
<div my-directive></div>
3.3,更换模板元素

    你可以把指令模板作为定义它的AngularJS模板元素的子模板来添加,也可以通过replace属性来替换它。为了说明这一点,亲看下面的指令:

directive('myDirective',function(){
	return{
		replace:true,
		templateUrl:'<div>directive</div>'
		};
	});

    然后查看下面模板代码:

<div>
    <span my-directive></span>
</div>

    编译器看到了replace是true,并对内部<span>元素进行替换,结果如下所示:

<div>
   <div>directive</div>
</div>
3.4,转置外部作用域

    你可以在指令的定义中把transclude选项设置为true或false。如果它被设置为true,则该指令的内部组件可以反问指令以外的作用域。你还必须在指令模板内的元素中包括ngTransclude指令。下面是实现transclude来从,myDirective指令模板访问在控制器作用域的title变量的一个示例:

angular.module('myApp',[]).
	directive('myDirective',function(){
		return{
			transclude:true,
			scope:{},
			templateUrl:'<div ng-tranclude>{{title}}</div>'
		};
	}).
	controller('myController',function($scope){
		$scope.title="myApplication";
	});
3.5,配置指令的作用域

    有时,你可能要把一个指令里面的作用域与该指令外面的作用域分离。这样做可以防止该指令在本地控制器改变值的可能性。指令定义允许你指定一个创建隔离作用域的作用域。隔离的作用域从外部与隔离该指令作用域,一防止该指令反问外部作用域,并防止外部作用域的控制器改变该指令作用域。例如,下面的例子从外部作用域隔离了该指令的作用域:

directive('myDirective',function(){
	return{
		scope:{},
		templateUrl:'/myDirective.html'
	};
});

    使用此代码,该指令具有一个完全空的隔离作用域。不过,你可能希望把在外部作用域的一些项目仍然映射到指令的作用域。你可以使用下面的前缀属性名,使局部作用域内的一些项目仍然映射到指令的作用域内。你可以使用下面的前缀属性名,使局部作用域内的变量在指令的作用域中可用。

  • @:把一个局部作用域内的字符串绑定到DOM属性的值中,该属性的值将在该指令作用域内可用
  • =:在局部作用域属性和指令作用域属性之间创建一个双向绑定
  • &:把在局部作用域内的函数绑定到指令作用域

    如果前缀后面没有跟着属性名,则使用该指令的属性名。例如:

    title:'@'

    title:'@title'

是一样的

    下面的代码显示了如何实现每一个不同的方法来把局部值映射到每一个指令的隔离作用域:

angular.module('myApp',[]).
	controller('myController',function($scope){
		$scope.title="myApplication";
		$scope.myFunc = function(){
			console.log("out");
		};
	}).
	directive('myDirective',function(){
		return{
			scope:{title:'=',newFunc:"&myFunc",info:'@'},
			template:'<div ng-click="newFunc()">{{title}}:{{info}}</div>'
		};
	});

    下面的代码显示了如何在AngularJS模板中定义指令来提供必要的属性以映射这些属性:

<div my-directive
	my-func="myFunc()"
	title="title"
	info="SomeString"></div>
3.6,操纵DOM的链接功能

    当AngularJS的HTML编译器遇到一个指令时,它运行该指令的编译函数,这返回link()函数。link()函数被添加到AngularJS指令列表。一旦所有的指令都被编译完成,则HTML编译器根据优先级顺序调用link()函数。

    如果你想在自定义指令里面修改DOM,就应该使用一个link()函数。link()函数接受作用域,元素和指令相关的属性,让你直接在指令中操纵DOM。

    在link()函数里面,你处理指令元素上的$destory事件并清理任何必要的东西。link()函数也负责注册DOM监听器来处理浏览器事件。

    link()函数使用一下语法:

link:function(scope,element,attributes,[controller])

    scope参数是指令的作用域,element是指令将被插入的元素,attributes列出在该元素中定义的属性,而controller是由require选项指定的控制器。

    下面的指令显示了一个基本link()函数的实现,它设置一个作用域变量,将数据追加到DOM元素,实现了$destory事件处理程序,并添加了一个$watch到该作用域:

directive('myDirective',function(){
	return{
		scope:{title:'='},
		require: '^otherDirective',
		link:function(scope,elem,attr,otherController){
			scope.title = "new";
			elem.append("Linked");
			elem.on('$destory',function(){
				//清理代码
			});
			scope.$watch('title',funciton(newVal){
				//监视代码
			});
		}
	};
3.7,添加一个控制器到指令

    你可用利用指令定义的controller属性来为一个指令添加自定义控制器。这使你可用为指令模板提供控制器支持。例如,下面的代码添加了一个简单的控制器,它设置了一个作用域值和函数:

directive('myDirective',function(){
	return{
		scope:{title:'='},
		controller:funciton($scope){
			$scope.title = "new";
			$scope.myFunction = function(){
			};
		}
	};
});

    你也可以使用require选项,以确保控制器对该指令是可用的。require选项使用require:'^controller'语法指示注入器服务在父上下文中查看,直到找到控制器为止。一下是在一个指令中要求控制器myController的一个例子:

directive('myDirevtive',function(){
	return{
		require:'^myController'
	};
});
3.8,创建自定义指令

    可以定义的自定义指令类型真的是无限的,这使得AngularJS真正具有可扩展性。自定义指令是AngularJS中解释起来最复杂的部分。下面是两种自定义指令的例子:

                                    directive_custom.js:实现彼此交互的自定义指令

angular.module('myApp',[]).
	directive('myPhotos',function(){
		return{
			restrict:'E',
			transclude:true,
			scope:{},
			controller:function($scope){
				var photos= $scope.photos = [];
				$scope.select = function(photo){
					angular.forEach(photos,function(photo){
						photo.selected = false;
					});
					photo.selected = true;
				};
				this.addPhoto = function(photo){
					photos.push(photo);
				};
			},
			templateUrl:'my-photo.html'
		};
	}).
	directive('myPhoto',function(){
		return{
			require:'^myPhtots',
			restrict:'E',
			transclude:true,
			scope:{title:'@'},
			link:function(scope,elem,attrs,photosControl){
				photosControl.addPhoto(scope);
			},
			template:'<div ng-show="selected" ng-transclude></div>'
		};
	});

                            directive_custom.html:实现嵌套的自定义指令的AngularJS模板

<!doctype html>
<html ng-app="myApp">
<head>
	<title>AngularJS Custom Directive</title>
</head>
<body>
	<my-photos>
		<my-photo title="Flower">
			<img src="/images/flower.jpg" height="150px"/>
		</my-photo>
		<my-photo title="Arch">
			<img src="/images/arch.jpg" height="150px"/>
		</my-photo>
		<my-photo title="Lake">
			<img src="/images/lake.jpg" height="150px" />
		</my-photo>
	</my-photos>
	<script src="js/angular.js"></script>
	<script src="js/directive_custom.js"></script>
</body>
</html>

                    my_photos.html:为myPhotos自定义指令提供根元素的AngularJS局部模板

<div>
	<span ng-repeat="photo in photos" ng-class="{active:photo.selected}">
	<a href="" ng-click="select(photo)">{{photo.title}}</a>
	</span>
	<div ng-transclude></div>
</div>

4,小结

    AngularJS指令扩展HTML的行为。可以把指令作为HTML元素,属性和类来应用到AngalrJS模板。可以利用JavaScript代码来定义指令的功能。AngularJS提供了多种内置的指令用于对表达元素进行交互,把作用域内的数据绑定到视图,并与浏览器事件进行交互。例如,ngModel直接把一个表单元素的值绑定到作用域。当作用域的值发生变化时,由该元素显示的值也跟着变化,反之亦然。

    AngularJS最强大的功能之一是创建自己的自定义指令的能力。只需要在一个Module对象上使用directive()方法就你那个在代码中实现自定义指令。然而,指令也可以非常复杂,因为它们有无数种可以被实现的方式。

猜你喜欢

转载自blog.csdn.net/qq_39263663/article/details/80543017
今日推荐