Angular内置指令

Angular内置指令


指令允许你更改HTML标签的具体操作。这是一项非常强大的功能,它允许你创建自定义标签。使用指令标签会告知编译器在DOM元素中添加某些功能,甚至能够对其进行改动。AngularJS中还提供大量预置指令,你可以根据实际需要进行选择。

指令使我们用来扩展浏览器能力的技术之一。在DOM编译期间,和HTML关联着的指令会被检测到,并且被执行。这使得指令可以为DOM指定行为,或者改变它。
AngularJS有一套完整的、可扩展的、用来帮助web应用开发的指令集,它使得HTML可以转变成“特定领域语言(DSL)”。

指令遵循驼峰式命名,如ngBind。指令可以通过使用指定符号转化成链式风格的的名称来调用,特定符号包括 : ,-,_。你好可以选择给指令加上前缀,比如“x-”,“data-”来让它符合html的验证规则。这里有以下可以用的指令名称例子:ng:bind, ng-bind, ng_bind, x-ng-bind , data-ng-bind。

指令可以做为元素名,属性名,类名,或者注释。


1. Application指令


(1) ng-app 

任何标记ng-app的DOM元素会创建$rootScope.$rootScope是作用域链的起点,任何嵌套在里面的指令都会继承它.在JS里面通过run方法来访问$rootScope.
ng-app这个指令比较特殊,一个html文档最好只出现一次,如果出现多次也是只有第一个起作用,并且可以出现在html文档的任何一个元素上。
ng-app作用是告诉子元素一下的指令是归angularJs的,angularJs会识别的。
ng-app的值可以为空,当然在练习的时候,在项目中则一定是要赋值的。也就是后面所说的模块。angularJs的使用,不是有一句一定要牢记在的话“一切都是由模块开始的”。
例如:
 
scope是angularJS中的作用域(其实就是存储数据的地方),很类似javascript的原型链 。搜索的时候,优先找自己的scope,如果没有找到就沿着作用域链向上搜索,直至到达根作用域rootScope。

$rootScope是由angularJS加载模块的时候自动创建的,每个模块只会有1个rootScope。rootScope创建好会以服务的形式加入到 $injector中。也就是说通过 $injector.get("$ rootScope ");能够获取到某个模块的根作用域。更准确的来说,$rootScope是由angularJS的核心模块ng创建的。

scope是html和单个controller之间的桥梁,数据绑定就靠他了。rootscope是各个controller中scope的桥梁。用rootscope定义的值,可以在各个controller中使用。

    
{{title}}
{{item}}
{{title}}
{{item}}
看一下页面上的展示:
Angular内置指令_第1张图片
在网上看到一些文章说到$injector与$rootscope也会有关联,具体的关联后面的会学习到,当前这一块就先了解到这里吧。

(2) ng-controller

该指令会为嵌套在里面的指令创建一个子作用域,避免所有的操作与模型都在$rootScope上.不同的controller他们scope对象是不一样的,即使都是用了同名称的变量,可以看出controller之间是封闭的,可是有时候我们面对两个模块之间进行数据交互,必然在两个controller之间进行通信,这就涉及到angular中的service操作,或者是使用$rootscope,后面学习服务。

请看上面的例子。


2.布尔属性指令


ng-disabled: 用于select button input textarea ,禁止输入

ng-readonly : 只读

ng-checked : 单选,多选的选中状态,ng-checked控制radio和checkbox的选中状态

ng-selected : 下拉列表的选中

ng-multiple控制多选



3.binding指令


(1) ng-bind \ ng-model \ {{}}

AngularJS的数据绑定有三种分别为{{}}、ng-bind和ng-model
{{}}和ng-bind都是单向绑定,由作用于$scope到view层,且在HTML控件(HTML控件有:input、select、button和textarea)中不可显示。
ng-model是双向绑定,$scope<--->view层。

看一个例子:

$.title的value: {{title}}

$.title的value:

然后对应页面上的结果是:

Angular内置指令_第2张图片

第二个红色框表示ng-bind应用有input标签上不可显示,没有作用。
第一个和第三个分别是{},以及ng-bind在span上的展示,可以看到{{}}可以保持原有值得情况下添加响应的内容,但是ng-bind确实会将原来的内容全部替换成新的内容。

(2) ng-init

初始化应用时创建一个变量,ng-init 指令添加一些不必要的逻辑到 scope 中,建议你可以在控制器中 ng-controller 指令执行它 。



4. style相关指令


(1) ng-class

angular 三种处理class

a. scope变量绑定。(不推荐使用,class应该放在html中,不应该占用controller $scope)


    
test ng-class
注意此时代码中使用的class不是ng-class。

b. 字符串数组形式

test ng-class
这种用法就是说showRed为true时,就给元素加上red这个class,如果variable为false就加上yellow这个class,这个在逻辑比较简单的时候还是蛮好用.

下面的例子可以通过option的选择来选择不同的class

    
test ng-class
上面的这种是对于需要通过true/false的值来进行同一种样式的选择,如果是对于不同的样式一次进行多个赋样式的话我们可以这样
test ng-class

注意这里的class是带有单引号的,与上面的有所不同。

c. 对象key/value处理


    
       
test ng-class
   
   
当showRed为true时,增加color样式;当fontSizeUpdate为true时,增加font样式。这种方式与第二种相比的好处在于,可以在ng-class中一次性操作过多个class文件,并且决定是否添加给当前元素。

(2) ng-style

ng-style用来绑定元素的css样式,其表达式的返回值为一个js对象,键为css样式名,值为该样式对应的合法取值。用法比较简单:
test ng-class
切记red中的单引号不能丢了


(3) ng-show / ng-hide

对于比较常用的元素显隐控制,ng也做了封装,ng-show和ng-hide的值为boolean类型的表达式,当值为true时,对应的show或hide生效。框架会用display:block和display:none来控制元素的显隐。
test ng-class
这个例子是不是有点矛盾,最后这个div会show出来,因为样式后面会覆盖前面的样式。

5. 表单指令

常用的表单验证指令 

(1) 必填项验证

某个表单输入是否已填写,只要在输入字段元素上添加HTML5标记required即可:
  

(2) 最小长度

验证表单输入的文本长度是否大于某个最小值,在输入字段上使用指令ng-minleng= "{number}":
 

(3) 最大长度

验证表单输入的文本长度是否小于或等于某个最大值,在输入字段上使用指令ng-maxlength="{number}":

(4) 模式匹配

使用ng-pattern="/PATTERN/"来确保输入能够匹配指定的正则表达式:
 

电子邮件

验证输入内容是否是电子邮件,只要像下面这样将input的类型设置为email即可:
 

数字

验证输入内容是否是数字,将input的类型设置为number:
 

URL

验证输入内容是否是URL,将input的类型设置为 url:

ng form 表单验证示例 (针对以上的几种验证)




    
    Angular
    
    
    


    
1.必填项:{{user.name}}   $pristine 【没修改】:{{myForm.name.$pristine }}   $dirty【修改过】:{{myForm.name.$dirty}}   $invalid【验证失败】:{{myForm.name.$invalid}}   $invalid【验证成功】:{{myForm.name.$valid}}   required:{{myForm.name.$error.required}}  

2.最小长度=5:{{user.minlength}} $pristine 【没修改】:{{myForm.minlength.$pristine }}   $dirty【修改过】:{{myForm.minlength.$dirty}}   $invalid【验证失败】:{{myForm.minlength.$invalid}}   $invalid【验证成功】:{{myForm.minlength.$valid}}   $error【错误详情】:{{myForm.minlength.$error}}  

接下来我们会在这个示例中去观察一些点(对于上面的验证):



首先看一下页面上展示的红色框内,这里对应的代码为:

1.必填项:{{user.name}}   $pristine 【没修改】:{{myForm.name.$pristine }}   $dirty【修改过】:{{myForm.name.$dirty}}   $invalid【验证失败】:{{myForm.name.$invalid}}   $invalid【验证成功】:{{myForm.name.$valid}}   required:{{myForm.name.$error.required}}  

2.最小长度=5:{{user.minlength}} $pristine 【没修改】:{{myForm.minlength.$pristine }}   $dirty【修改过】:{{myForm.minlength.$dirty}}   $invalid【验证失败】:{{myForm.minlength.$invalid}}   $invalid【验证成功】:{{myForm.minlength.$valid}}   $error【错误详情】:{{myForm.minlength.$error}}  

a. 提到这里就不得不提一些form属性:
formName.inputFieldName.$pristine :布尔值属性,表示用户是否修改了表单。如果为ture,表示没有修改过;false表示修改过
formName.inputFieldName.$dirty    :布尔型属性,当且仅当用户实际已经修改的表单。不管表单是否通过验证
formName.inputFieldName.$valid  :布尔型属性,它指示表单是否通过验证。如果表单当前通过验证,他将为true
formName.inputFieldName.$invalid  :布尔型属性,未通过验证的表单
这里的formName指的是form的name属性值,inputFieldName指的是input标签的name属性值。例如myForm.name.$pristine。


b. 这里的这些验证情况当然通过ng-submit提交表单的时候传入表单的name,然后在处理方法中查看验证信息,如下图


c. 对于表单验证初始都是没有值的,然后我们把当前例子中的初始值去掉,然后看一下页面的显示:


我们可以看到必填项已经显示红框了。这样其实是不对的,因为用户还没有输入,你的验证就不应该开始,所以我们需要修改一代码,
我们把ng-invalid换一个名称ng-error,然后修改一下input的代码。
 
这个时候我们的验证就会在用户输入之后才开始,关键点就是:myForm.name.$dirty && myForm.name.$invalid。


d. 在(3)中我们提到了ng-invalid class,这个class的名称不是我们自定义的,是ng自己定义的名称。
.ng-valid         {  }
.ng-invalid     {  }
.ng-pristine     {  }
.ng-dirty         {  }
.ng-invalid-required         {  }
.ng-invalid-minlength         {  }
.ng-valid-max-length         {  }
它们对应着表单输入字段的特定状态。
例如当某个字段中的输入非法时,.ng-invlid类会被添加到这个字段上。 你可以编辑自己喜欢的CSS . 你可以私有定制化这些类来实现特定的场景应用.

e. 还有就是其实浏览器对于表单的验证有着自己的默认行为,例如下图


Angular内置指令_第3张图片


我们想要去除这些默认的表单行为,我们需要在form标签中加上novalidate属性。

(5) ng-true-value / ng-false-value

当我们点击checkbox 选中复选框时,ng-model 的绑定默认值是true,取消选中时为false.如果我们需要获取的值为字符串或者数字呢?
那么就需要用到 ng-true-value 和ng-false-value.
 //注意 ng-true-value 中的值 如果需要显示字符串的话必须使用单引号.

然后我们看一下具体的这个input标签内部的信息:


请看红色框内的信息,一个是$viewValue($viewValue属性保存着更新视图所需的实际字符串),另一个是$modelValue($modelValue由数据模型持有。$modelValue和$viewValue可能是不同的,取决于$parser流水线是否对其进行了操作。),我们可以在modelValue中查看到hello world,具体这两个属性的值等到我们学习到自定义指令的时候再去看,我们现在知道在哪里可以取值的就好了。

(6) ng-option

ng-options不需要option,会自动生成,ng-options 一定要和ng-model 搭配

a. 先看一个简单的方式(label for value in array)


    

usage:label for value in array

选项,{{optData.Selected}}


b. 自定义下拉显示名称(label for value in array) label可以根据需要拼接出不同的字符串


    

usage:label for value in array

选项,{{optData.Selected}}


主要的改变是:
在b的基础上加上group by ~.


d. ng-options 自定义ngModel的绑定

下面selected的值为optData的id,这里show的是ProductName,选择的是id

    

usage:label for value in array

选项,{{optData.Selected}}

可以看到show出来的值与选择获取到的值是不一样的:




e. 二级菜单 


    

(7) ng-selected 指令用于设置
choose dog. choose cat. choose other.

然后看一下html的元素:


其实可以看出来和ng-if有点相似。
和ng-switch相关的还有一个on,我们可以将
 改成
 


(5) ng-transclude 规定填充的目标位置

具体的用法我想等到学习玩自定义指令之后再去学习。

(6) ng-include : 可以加载,编辑,并包含外部HTML片段到当前应用中.

filename    文件名,可以使用表达式来返回文件名。
onload      可选, 文件载入后执行的表达式。
autoscroll  可选,包含的部分是否在指定视图上可滚动。


 特别说明:
* ng-include,如果单纯指定地址,必须要加引号
* ng-include,加载外部html,script标签中的内容不执行,不能加载,如果需要控制器处理需要在主页中注册
* ng-include,加载外部html中含有style标签样式可以识别
* ng-inclue,记载外部html中的link标签可以加载

举例:
{{title}}
The content is belong to index.cshtml.




{{title}}
The content is from another html model. I am rod chen.
然后看一下界面效果以及页面中加载的element



从绿色框中看到的内容对应了上面特别说明的内容,自行领会(因为图片上传的限制,所以图片被缩小了)。

(7) ng-view 

涉及到路由的信息,所以后面会有单独的文章去学习。

7. event事件指令


(1) ng-click

适用标签:所有
触发条件:单击
click me
  

(2) ng-dblclick

适用标签:所有
触发条件:双击
click me

(3) ng-blur

适用标签:a / input / select / textarea
触发条件:失去焦点
link

(4) ng-focus

适用标签:a / input / select / textarea
触发条件:获取焦点
link

(5) ng-change

适用标签:input / select / textarea
触发条件:model更新

对于input标签,当我每按下key的时候,input都会触发change,对于select则是不同option的切换。

(6) ng-copy

适用标签:所有 HTML 元素都支持。一般常用的就是input和textarea。
触发条件:复制。鼠标右键复制和快捷键Ctrl+C都会触发。


(7) ng-cut

适用标签:a / input / select / textarea
触发条件:剪切。鼠标右键剪切和快捷键Ctrl+X都会触发。


(8) ng-paste

适用标签:a / input / select / textarea
触发条件:粘贴。鼠标右键粘贴和快捷键Ctrl+V都会触发。


(9) ng-keydown

适用标签:所有
触发条件:键盘按键按下
要把$event传过去,一般都是要判断按了哪个按键的。


(10) ng-keyup

适用标签:所有
触发条件:键盘按键按下并松开



(11) ng-keypress

适用标签:所有
触发条件:键盘按键按下


(12) keydown,keypress,keydown三者区别

引发事件的按键
非字符键不会引发 KeyPress 事件,但非字符键却可以引发 KeyDown 和 KeyUp 事件。

事件引发的时间
KeyDown 和 KeyPress 事件在按下键时发生,KeyUp 事件在释放键时发生。

事件发生的顺序
KeyDown -> KeyPress -> KeyUp。如果按一个键很久才松开,发生的事件为:KeyDown -> KeyPress -> KeyDown -> KeyPress -> KeyDown -> KeyPress -> ... -> KeyUp。

KeyDown触发后,不一定触发KeyUp,当KeyDown 按下后,拖动鼠标,那么将不会触发KeyUp事件。
KeyPress主要用来捕获数字(注意:包括Shift+数字的符号)、字母(注意:包括大小写)、小键盘等除了F1-12、SHIFT、Alt、Ctrl、Insert、Home、PgUp、Delete、End、PgDn、ScrollLock、Pause、NumLock、{菜单键}、{开始键}和方向键外的ANSI字符。
KeyDown 和KeyUp 通常可以捕获键盘除了PrScrn所有按键(这里不讨论特殊键盘的特殊键)。
KeyPress 只能捕获单个字符。
KeyDown 和KeyUp 可以捕获组合键。
KeyPress 可以捕获单个字符的大小写。
KeyDown和KeyUp 对于单个字符捕获的KeyValue 都是一个值,也就是不能判断单个字符的大小写。
KeyPress 不区分小键盘和主键盘的数字字符。
KeyDown 和KeyUp 区分小键盘和主键盘的数字字符。
其中PrScrn 按键KeyPress、KeyDown和KeyUp 都不能捕获。

(13) ng-mousedown

适用标签:所有
触发条件:鼠标按下,左右中间按下都会触发

(14) ng-mouseup

适用标签:所有
触发条件:鼠标按下弹起,左右中间按下弹起都会触发

(15)ng-mouseenter

适用标签:所有
触发条件:鼠标进入

(16) ng-mouseleave

适用标签:所有
触发条件:鼠标离开

(17) ng-mousemove

适用标签:所有
触发条件:鼠标移动

(18)ng-mouseover

适用标签:所有
触发条件:鼠标进入

8. 特殊的ng-src / ng-href指令

(1) ng-href: 引入A标签链接的URL,多用于动态生成URL,存在一个问题就是如果还没动态生成URL,用户就点击了,那么就会跳转到404页面.Angular会等到插值生效再执行链接点击行为.


Test ng-href

Test ng-href($timeout)
Test ng-href(timeout)

为了测试这个指令我写了上面的这个例子:
在页面渲染完成之后没有过了我写的5000ms钱,看一下页面的加载情况:
Angular内置指令_第5张图片

这个时候由于href2还没有生成,所以这个时候这个a标签是不可以点击的,这也是上面的描述。

然后再看一下经过5000ms之后页面的渲染:
Angular内置指令_第6张图片

可以看到href2动态生成之后,a标签页可以点击了,至于href3存在的意义在于说明这个地方我们只可以使用$timeout,而不能使用setTimeout来进行时间的延迟,否则的话不会有效果。

至于原因我没有去了解,但是大致猜测一下,angular.js的$timeout指令对window.setTimeout做了一个封装,它的返回值是一个promise对象,promise是一个基于任务队列的对象,但是原生的setTimeout基于事件循环队列的,当执行setTimeout的时候尽管我们已经给予href3赋值,但是这个$scope对象已经返回到angular了。具体的原因需要我们真正了解到angular执行的机制才能了解到了,为了证明前面的话,现在我们将code修改一下。

然后我们等到6000ms之后再看一下结果:




看到这个时候我们的href3的效果已经在页面上显示出来了,这也是promise基于任务队列的功能展示,相信具体的DOM在angular环境下的渲染会和任务队列有关系,期待后面的学习。

(2) ng-src:Angular会告诉浏览器在ng-src表达式生效之前不会显示图像.

这个其实和ng-href类似,在src没有动态生成之前,图像是不会在页面上显示,此时的html

当ng-src生成时候,html的结果如下:


暂时先把内置指令学习到这里,接下来就是自定义指令已经本文里遗留下来的几个指令!

你可能感兴趣的:(Angular)