JS AngualrJs 指令

本文基于 AngularJs 1.x 版本


内置指令

 

布尔属性

根据HTML标准的定义,布尔属性代表一个 true 或 false 值。

当这个属性出现时,这个属性的值就是 true (无论实际定义的值是什么)。如果未出现,这个属性的值就是 false 。

因此,AngularJS 提供了一组带有 ng- 前缀的布尔属性,通过运算表达式的值来决定在目标元素上是插入还是移除对应的属性。

 

ng-disabled
使用 ng-disabled 可以把 disabled 属性绑定到以下表单输入字段上:
input ( text 、 checkbox 、 radio 、 number 、 url , email 、 submit )
textarea | select | button

 

ng-readonly

可以将某个返回真或假的表达式同是否出现 readonly 属性进行绑定

 

ng-checked

标准 checked 属性是一个布尔属性,不需要进行赋值,通过 ng-checked 将某个表达式同是否出现 checked 属性进行绑定。


ng-selected

可以对是否出现 option 标签的 selected 属性进行绑定


类布尔属性

ng-href | ng-src | ng-class |ng-style

 

ng-app 和 ng-controller

ng-app 和 ng-controller 是特殊的指令,因为它们会修改嵌套在它们内部的指令的作用域。
ng-app 为AngularJS应用创建 $rootScope。
ng-controller 则会以 $rootScope 或另外一个 ng-controller 的作用域为原型创建新的子作用域。
任何具有 ng-app 属性的DOM元素将被标记为 $rootScope 的起始点。
$rootScope 是作用域链的起始点,任何嵌套在 ng-app 内的指令都会继承它。
在 JavaScript 代码中通过 run 方法来访问 $rootScope 。
内置指令 ng-controller 是为嵌套在其中的指令创建一个子作用域,避免将所有操作和模型都定义在 $rootScope 上。
用这个指令可以在一个DOM元素上放置控制器。
ng-controller 接受一个参数 expression ,这个参数是必需的。expression 参数是一个AngularJS表达式
子 $scope 只是一个JavaScript对象,其中含有从父级 $scope 中通过原型继承得到的方法和属性,包括应用的 $rootScope。
嵌套在 ng-controller 中的指令有访问新子 $scope 的权限,但是要牢记每个指令都应该遵守的和作用域相关的规则。

 

ng-include

使用 ng-include 可以加载、编译并包含外部HTML片段到当前的应用中。模板的URL被限制在与应用文档相同的域和协议下
在同一个元素上添加 onload 属性可以在模板加载完成后执行一个表达式
使用 ng-include 时AngularJS会自动创建一个子作用域。
如果你想使用某个特定的作用域,必须在同一个DOM元素上添加 ng-controller ="ControllerA"指令。

 

ng-switch 

ng-switch 指令和 ng-switch-when 及 on="propertyName" 一起使用,可以在 propertyName 发生变化时渲染不同指令到视图中
在 switch 被调用之前用 ng-switch-default 来输出默认值

 

ng-view

ng-view 指令用来设置将被路由管理和放置在HTML中的视图的位置

 

ng-if

使用 ng-if 指令可以完全根据表达式的值在DOM中生成或移除一个元素。
ng-if 同 ng-show 和 ng-hide 指令最本质的区别是,它不是通过CSS显示或隐藏DOM节点,而是真正生成或移除节点

 

ng-repeat

ng-repeat 用来遍历一个集合或为集合中的每个元素生成一个模板实例。
集合中的每个元素都会被赋予自己的模板和作用域。同时每个模板实例的作用域中都会暴露一些特殊的属性。
$index :遍历的进度(0... length-1 )。
$first :当元素是遍历的第一个时值为 true 。
$middle :当元素处于第一个和最后元素之间时值为 true 。
$last :当元素是遍历的最后一个时值为 true 。
$even :当 $index 值是偶数时值为 true 。
$odd :当 $index 值是奇数时值为 true

 

ng-init

ng-init 指令用来在指令被调用时设置内部作用域的初始状态

语法是AngularJS内置的模板语法,它会在内部 $scope 和视图之间创建绑定。
事实上它也是指令,虽然看起来并不像,实际上它是 ng-bind 的简略形式,用这种形式不需要创建新的元素,因此它常被用在行内文本中。
注意,在屏幕可视的区域内使用 会导致页面加载时未渲染的元素发生闪烁,用 ng-bind 可以避免这个问题。

除使用 ng-bind 来避免未渲染元素闪烁,还可以在含有 的元素上使用 ng-cloak 指令:
ng-cloak 指令会将内部元素隐藏,直到路由调用对应的页面时才显示出来。

 

ng-model

ng-model 指令用来将 input 、 select 、 text area 或自定义表单控件同包含它们的作用域中的属性进行绑定。

它可以提供并处理表单验证功能,在元素上设置相关的CSS类( ng-valid 、ng-invalid 等),并负责在父表单中注册控件。
它将当前作用域中运算表达式的值同给定的元素进行绑定。如果属性并不存在,它会隐式创建并将其添加到当前作用域中
我们应该始终用 ngModel 来绑定 $scope 上一个数据模型内的属性,而不是 $scope 上的属性,这可以避免在作用域或后代作用域中发生属性覆盖。

 

ng-show 和 ng-hide

ng-show 和 ng-hide 根据所给表达式的值来显示或隐藏HTML元素。

 

ng-change 

ng-change 指令会在表单输入发生变化时计算给定表达式的值。这个指令需要和 ngModel 联合起来使用。

 

ng-form

ng-form 用来在一个表单内部嵌套另一个表单。
普通的HTML form 标签不允许嵌套,但 ng-form 可以。
这意味着内部所有的子表单都合法时,外部的表单才会合法。验证需要name属性
下面的CSS类会根据表单的验证状态自动设置:
合法时设置 ng-valid | 不合法时设置 ng-invlid | 未进行修改时设置 ng-pristion | 进行过修改时设置 ng-dirty
Angular 不会将表单提交到服务器,除非它指定了 action 属性。

要指定提交表单时调用哪个 JavaScript方法,使用下面两个指令中的一个。

ng-submit :在表单元素上使用 | ng-click :在第一个按钮或 submit 类型( input[type=submit] )的输入字段上使用。

ng-click 用来指定一个元素被点击时调用的方法或表达式。

ng-select 用来将数据同HTML的 select 元素进行绑定。这个指令可以和 ng-model 以及 ng-options 指令一同使用,构建精细且表现优良的动态表单。

ng-submit 用来将表达式同 onsubmit 事件进行绑定。这个指令同时会阻止默认行为(发送请求并重新加载页面),除非表单不含有 action 属性。

 

ng-class

使用 ng-class 动态设置元素的类,方法是绑定一个代表所有需要添加的类的表达式。
重复的类不会添加。当表达式发生变化,先前添加的类会被移除,新类会被添加。

 

ng-attr-(suffix)
当 AngularJS 编译 DOM 时会查找花括号内的表达式。
这些表达式会被自动注册到 $watch 服务中并更新到 $digest 循环中,成为它的一部分
有时浏览器会对属性会进行很苛刻的限制,这时我们就可以使用该指令绑定一个花括号表达式。

 

指令详解

 

directive(name,factory_function)

可以接受两个参数:

1. name (字符串) 指令的名字,用来在视图中引用特定的指令。
2. factory_function (函数) 这个函数返回一个对象,其中定义了指令的全部行为。 $compile 服务利用这个方法返回的对象,在DOM调用指令时来构造指令的行为。

我们也可以返回一个函数代替对象来定义指令,但是通过对象来定义是最佳的方式。
当返回一个函数时,这个函数通常被称作链接传递(postLink)函数,利用它我们可以定义指令的链接(link)功能。
由于返回函数而不是对象会限制定义指令时的自由度,因此只在构造简单的指令时才比较有用。

AngularJS编译器会解析主HTML的DOM中的元素、属性、注释和CSS类名中使用了这个名字的地方,并在这些地方引用对应的指令。
当它找到某个已知的指令时,就会在页面中插入指令所对应的DOM元素。

当AngularJS在DOM中遇到具名的指令时,会去匹配已经注册过的指令,并通过名字在注册过的对象中查找。
此时,就开始了一个指令的生命周期,指令的生命周期开始于 $compile 方法并结束于 link 方法

 

一个指令时可以使用的全部设置选项:

 1 angular.module('myApp', [])
 2     .directive('myDirective', function () {
 3         return {
 4             restrict: String,
 5             priority: Number,
 6             terminal: Boolean,
 7             template: String or Template Function: function (tElement, tAttrs)(...
 8             },
 9             templateUrl: String,
10             replace: Boolean or String,
11             scope: Boolean or Object,
12             transclude: Boolean,
13             controller: String or
14             function (scope, element, attrs, transclude, otherInjectables) { ...
15             },
16             controllerAs: String,
17             require: String,
18             link: function (scope, iElement, iAttrs) { ...
19             },
20             compile: // 返回一个对象或连接函数,如下所示:
21                 function (tElement, tAttrs, transclude) {
22                     return {
23                         pre: function (scope, iElement, iAttrs, controller) { ...
24                         },
25                         post: function (scope, iElement, iAttrs, controller) { ...
26                         }
27                     }
28                     // 或者
29                     return function postLink(...) { ...
30                     }
31                 }
32         };
33     });

 

restrict 
restrict 是一个可选的参数。
它告诉AngularJS这个指令在DOM中可以何种形式被声明。默认AngularJS认为 restrict 的值是 A ,即以属性的形式来进行声明。
可选值如下:

E(元素)| A(属性,默认值)| C(类名)| M(注释)

这些选项可以单独使用,也可以混合在一起使用,属性是用来声明指令最常用的方式,因为它能在包括老版本的IE浏览器在内的所有浏览器中正常工作

 

priority

priority 优先级参数可以被设置为一个数值。大多数指令会忽略这个参数,使用默认值0,但也有些场景设置高优先级是非常重要甚至是必须的。
例如, ngRepeat 将这个参数设置为1000,这样就可以保证在同一元素上,它总是在其他指令之前被调用。
如果一个元素上具有两个优先级相同的指令,声明在前面的那个会被优先调用。
如果其中一个的优先级更高,则不管声明的顺序如何都会被优先调用:具有更高优先级的指令总是优先运行。

 

terminal

terminal 是一个布尔型参数,可以被设置为 true 或 false 。
这个参数用来告诉AngularJS停止运行当前元素上比本指令优先级低的指令。但同当前指令优先级相同的指令还是会被执行。
如果元素上某个指令设置了 terminal 参数并具有较高优先级,就不要再用其他低优先级的指令对其进行修饰了,因为不会被调用。

 

template

template 参数是可选的,必须被设置为以下两种形式之一:
一段HTML文本 | 一个可以接受两个参数的函数,参数为 tElement 和 tAttrs ,并返回一个代表模板的字符串。
如果模板字符串中含有多个DOM元素,或者只由一个单独的文本节点构成,那它必须被包含在一个父元素内。换句话说,必须存在一个根DOM元素
每一行末尾加上反斜线,这样 AngularJS 能正确解析多行字符串。在实际生产中,
更好的选择是使用 templateUrl 参数引用外部模板,因为多行文本阅读和维护起来都是一场噩梦。

 

templateUrl 

templateUrl 是可选的参数,可以是以下类型:
一个代表外部HTML文件路径的字符串 | 一个可以接受两个参数的函数,参数为 tElement 和 tAttrs ,并返回一个外部HTML文件路径的字符串。

 

replace 

replace 是一个可选参数,如果设置了这个参数,值必须为 true ,因为默认值为 false 。
默认值意味着模板会被当作子元素插入到调用此指令的元素内部

 

scope 

scope 参数是可选的,可以被设置为 true 或一个对象。默认值是 false 。
当 scope 设置为 true 时,会从父作用域继承并创建一个新的作用域对象。
如果一个元素上有多个指令使用了隔离作用域,其中只有一个可以生效。只有指令模板中的根元素可以获得一个新的作用域。因此,对于这些对象来说 scope 默认被设置为 true 。
隔离作用域可能是 scope 属性三个选项中最难理解的一个,但也是最强大的。
具有隔离作用域的指令最主要的使用场景是创建可复用的组件,组件可以在未知上下文中使用,并且可以避免污染所处的外部作用域或不经意地污染内部作用域。
创建具有隔离作用域的指令需要将 scope 属性设置为一个空对象 {} 。如果这样做了,指令的模板就无法访问外部作用域了
使用无数据的隔离作用域并不常见。AngularJS提供了几种方法能够将指令内部的隔离作用域,同指令外部的作用域进行数据绑定。
值传递绑定: @ (or @attr)
双向数据绑定:= (or =attr) 就像普通的数据绑定一样,本地属性会反映出父数据模型中所发生的改变。
父级作用域绑定: & (or &attr) 可以对父级作用域进行绑定,在其中运行函数。意味着对这个值进行设置时会生成一个指向父级作用域的包装函数。要调用带有一个参数的父方法,我们需要传递一个对象,这个对象的键是参数的名称,值是要传递给参数的内容。

 

transclude

transclude 是一个可选的参数。如果设置了,其值必须为 true ,它的默认值是 false 。
嵌入通常用来创建可复用的组件,典型的例子是模态对话框或导航栏

 

controller 

controller 参数可以是一个字符串或一个函数。当设置为字符串时,会以字符串的值为名字,来查找注册在应用中的控制器的构造函数
控制器中有一些特殊的服务可以被注入到指令当中。这些服务有:
$scope 与指令元素相关联的当前作用域 | $element 当前指令对应的元素 | $attrs 由当前元素的属性组成的对象 | $transclude 嵌入链接函数会与对应的嵌入作用域进行预绑定。
指令的控制器和 link 函数可以进行互换。
控制器主要是用来提供可在指令间复用的行为,但链接函数只能在当前内部指令中定义行为,且无法在指令间复用。

 

controllerAs 

controllerAs 参数用来设置控制器的别名,可以以此为名来发布控制器,并且作用域可以访问 controllerAs 。这样就可以在视图中引用控制器,甚至无需注入 $scope 。

 

require 

require 参数可以被设置为字符串或数组,字符串代表另外一个指令的名字。 require 会将控制器注入到其值所指定的指令中,并作为当前指令的链接函数的第四个参数
字符串或数组元素的值是会在当前指令的作用域中使用的指令名称。
require 参数的值可以用下面的前缀进行修饰,这会改变查找控制器时的行为:
? 如果在当前指令中没有找到所需要的控制器,会将 null 作为传给 link 函数的第四个参数。
^ 如果添加了 ^ 前缀,指令会在上游的指令链中查找 require 参数所指定的控制器。
?^ 将前面两个选项的行为组合起来,我们可选择地加载需要的指令并在父指令链中进行查找。
没有前缀 如果没有前缀,指令将会在自身所提供的控制器中进行查找,如果没有找到任何控制器(或具有指定名字的指令)就抛出一个错误。

 

compile 

compile 选项可以返回一个对象或函数。
compile 选项本身并不会被频繁使用,但是 link 函数则会被经常使用。本质上,当我们设置了 link 选项,实际上是创建了一个 postLink() 链接函数,以便 compile() 函数可以定义链接函数。
通常情况下,如果设置了 compile 函数,说明我们希望在指令和实时数据被放到DOM中之前进行DOM操作,在这个函数中进行诸如添加和删除节点等DOM操作是安全的。
compile 和 link 选项是互斥的。如果同时设置了这两个选项,那么会把 compile 所返回的函数当作链接函数,而 link 选项本身则会被忽略。

 

posted @ 2018-07-19 08:37  Aaxuan  阅读(315)  评论(0编辑  收藏  举报