AngularJS 指令学习之一 指令简介

▼魔方 西西 提交于 2020-03-01 23:04:42

1.什么是AngularJS的指令?

  HTML元素由一个开始标签和一个结束标签组成,基于对此的理解,指令本质上就是AngularJS扩展具有自定义功能的HTML元素的途径。简单理解指令就是自定义的HTML元素和属性。

2.AngularJS指令的组成?

AngularJS指令包括内置和自定义指令,其中内置指令是打包在AngularJS内部的指令。所有内置指令的命名空间都使用ng作为前缀。

为了防止命名空间冲突,不要在自定义指令前加ng前缀。

内置指令包括:

ng-href,  ng-src 是类布尔属性;

ng-disabled, ng-checkedng-readonlyng-selectedng-classng-style 是布尔属性;

:根据HTML标准的定义,布尔属性代表一个 true 或 false 值。当这个属性出现时,这个属性的值就是 true (无论实际定义的值是什么) 。如果未出现,这个属性的值就是 false 。

3.创建一个自定义指令

<html ng-app="myApp">
<!-- 应用的$rootScope -->
<my-directive></my-directive>
</html>

我们首先已经创建了一个完整的HTML的文档,其中包含了AngularJS,并且DOM中已经用ng-App标识出应用的元素,当AngularJS编译HTML时就会调用指令。

angular.module('myApp',[])
		.directive('myDirective', function() {
			return {
				restrict: 'E',
				template: '\<div> <-- single root element -->\
							<a href="http://baidu.com">Click me</a>\
							<h1>When using two elements, wrap them in a parent element</h1>\
							</div>\'
				};
		});

通过AngularJS模块API中的.directive()方法,我们可以通过传入一个字符串和一个函数来注册一个新指令。其中字符串就是这个指令的名字,指令名应该是驼峰命名风格的,函数应该返回一个对象。 directive()方法返回的对象包含了用来定义和配置指令所需的方法和属性。

3.1 restrict (字符串)

restrict 是一个可选的参数,它告诉AngularJS这个指令在DOM中可以何种形式被声明。restrict设置可以指定以元素(E) 、属性(A) 、类(C)或注释(M)的格式来调用指令,用来声明前面创建指令的合法格式,默认AngularJS认为 restrict 的值是属性(A),即以属性的形式来进行声明。

// E(元素)
<my-directive></my-directive>

// A(属性,默认值)
<div my-directive="expression"></div>

// C(类名)
<div class="my-directive:expression;"></div>

// M(注释)
<--directive:my-directive expression-->

 

:虽然有很多方式可以声明指令,但是推荐使用属性方式声明,这是因为其跨浏览器兼容性比较好。尽量避免用注释方式来声明属性。这种方式最初被用来声明由多个标签组成的指令。这种方法在某些情况下特别有用,比如在 元素内使用 ng-repeat指 令 , 但 在 AngularJS 1.2 中 ng-repeat 可 以 通 过 ng-repeat-start 和ng-repeat-end 来更优雅地满足这个需求,注释模式就没有什么用武之地了。如果你对此很好奇,可以通过Chrome开发者工具的 element 标签观察一下使用ng-repeat 时被隐式添加的注释。

3.2 replace (布尔值)

replace 方法会使用自定义元素取代指令声明,而不是嵌套在其内部。replace 是一个可选参数,如果设置了这个参数,值必须为 true ,因为默认值为 false 。默认值意味着模板会被当作子元素插入到调用此指令的元素内部。

3.3 template (字符串或函数)  

template参数是可选的,可以是一段HTML文本,也可以是一个可以接受两个参数的函数,参数为 tElement 和 tAttrs ,并返回一个代表模板的字符串。

tElement 和 tAttrs 中的 t 代表 template ,是相对于 instance 的。如果模板字符串中含有多个DOM元素,或者只由一个单独的文本节点构成,那它必须被包含在一个父元素内。换句话说,必须存在一个根DOM元素,另外,注意每一行末尾的反斜线,这样AngularJS才能正确解析多行字符串。

在实际生产中,更好的选择是使用 templateUrl 参数引用外部模板,因为多行文本阅读和维护起来对我们来说都是一场噩梦。

//template.html

<div> 
 <a href="http://baidu.com">Click me</a>
 <h1>When using two elements, wrap them in a parent element</h1>
</div>
angular.module('myApp',[])
		.directive('myDirective', function() {
			return {
				restrict: 'E',
				templateUrl: 'template.html'
				};
		});

3.4 templateUrl (字符串或函数)  

templateUrl  是可选的参数,一个是代表外部HTML文件路径的字符串,一个是可以接受2个参数,参数为tElement和tAtrrs,并返回一个外部HTML文件路径的字符串。

无论哪种方式,模板的URL都将通过AngularJS内置的安全层,特别是$getTrustedResourceUrl,这样可以保护模板不会被不信任的源加载。

默认情况下,调用指令时会在后台通过Ajax来请求HTML模板文件。

:在本地开发时,需要在后台运行一个本地服务器,用以从文件系统加载HTML模板,否则会导致Cross Origin Request Script(CORS)错误。模板加载时异步的,意味着编译和链接要暂停,等待模板加载完成。但是,通过Ajax异步加载大量的模板将严重拖慢一个客户端的速度。为了避免延迟,可以在部署应用之前对HTML模板进行缓存。

 

参考资料

【美】Ari Lerner 著《AngularJS 权威教程》

 

转载时请注明:来自w-rain的个人博客

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!