文章目录
  1. 1. 内置指令
  2. 2. 指令定义
  3. 3. 指令定义解释
  4. 4. 引用文献

这篇文章主要包括ng中的内置指令、指令定义以及指令中的关键字段解释等问题。

内置指令

  1. 对于指令,可以把它简单的理解成在特定的DOM元素上运行的函数,指令可以扩展这个函数的功能。

    内置指令是打包在AngularJS中的内部指令,所有的内置指令的命名空间都使用了ng作为前缀,如ng-app。当AngularJs编译HTML时就会调用指令。调用指令意味着执行指令背后与之相关联的Javascript代码。指令可以和其他指令或属性组合在一起使用,这种组合使用的方法叫做合成。

  2. 常用基础属性内置指令:

    . 布尔属性 (当这个属性出现时,这个属性的值就是true,如果未出现,这个属性的值就是false):

    (1) ng-disabled
    (2) ng-readonly
    (3) ng-checked: 下面这个例子会默认把复选框勾选

    1
    2
    <label> someProperty = {{someProperty}}</label>
    <input type="checkbox" ng-chexked ="someProperty" ng-init="someProperty =true" ng-model="someProperty">

    (4) ng-selected

    1
    2
    3
    4
    5
    6
    <label> select two fish:</label>
    <input type="checkbox" ng-model="isTwoFish">
    <select class="" name="">
    <option>one Fish</option>
    <option ng-selected ="isTwoFish">Two Fish</option>
    </select>

    类布尔属性

    (1) ng-href :AngularJs 会等到差值生效后再执行连接行为 ng-href 与ng-src 能有效帮助重构和避免错误。
    (2)ng-src : AngularJs会告诉浏览器在ng-src 对应的表达式生效之前不要加载图像。

  3. 在指令中使用子作用域的内置指令:
    下面的指令会以父级作用域为原型生成子作用域,这种继承的机制可以创建一盒隔离层,用来将需要协同工作的方法和数据模型对象放在一起。

    (1) ng-app 位AngularJS应用穿件$rootScope,$rootScope是作用域链的起点,任何嵌套在ng-app中的指令都会继承它。
    可以在整个文档汇总只使用一次ng-app。 如果需要在一个页面中放置多个AngularJs应用,需要手动引导应用。
    (2) ng-controller 接收一个参数,这个参数必须,并且是一个AngularJs表达式。子$scope只是一个Javascript对象,其中包含从父级$scope中通过原型继 承得到的方法和属性。 $scope 对象的职责是承载DOM中指令共享的操作和类型。操作指的是$scope上的标准的JavaScript方法。模型指的是$scope上保存的包含瞬时状态数据的JavaScript对象。持久化状态的数据应该保存在服务中,服务的作用是处理模型的持久化。控制器应尽量简单,应尽量将业务逻辑移到服务和指令中。注意 $.. 是引用传递 ,$._ 是值传递。
    (3) ng-include 在使用这个指令时,AngularJs会自动创建一个子作用域,如果想使用某个特定的作用域,如ControllerA的作用域,必须在同一个DOM元素上添加ng-controller =”ControllerA”指令,这样当模板加载完成后,不会像往常一样从外部作用域继承并创建一个新的子作用域。
    (4) ng-switch 这个指令及 ng-switch-when 、on=”propertyName”一起使用时 可以在propertyName 发生变化是渲染不同指令到视图中。
    (5) ng-view
    (6) ng-if ng-if与ng-show、ng-hide指令最本质的区别是,它不是通过CSS显示或隐藏DOM节点,而是真正生成或移除节点。当一个元素被ng-if 从DOM中移除时,同它关联的作用域也会被销毁,而且当它重新加入DOM中时,会通过原型继承从它的父作用域生成一个新的作用域。而且ngIf 重新创建元素时用的是它们编译后的状态。
    (7) ng-repeat 集合中每个元素都会被赋予自己的模板和作用域。
    (8) ng-init
    (9) { { } }是ng-bind 简略形式, { { } }会导致页面加载时未渲染的元素发生闪烁,用ng-bind可以避免这个问题。 或者在含有 { { } }的元素上使用ng-cloak指令,ng-cloak指令会将内部元素隐藏,知道路由调用对应的页面才显示出来。
    (10) ng-form :表单可以嵌套
    (11) ng-attr-(suffix)当AngularJs编译DOM时会查找花括号{ { } }内的表达式,这些表达式会被自动注册到$watch服务中并更新到$digest循环中,成为它的一部分。但有时浏览器会对属性有限制 如svg,此时应使用ng-attr-{ {suffix} }

指令定义

当AngularJs 启动应用时,会把第一个参数当做一个字符串,并以此字符串为名注册第二个参数返回的对象,AngularJs编译器会解析主HTML的DOM中的元素、属性、注释和CSS类名中使用了这个名字的地方,并在这些地方引用对应的指令。指令的工厂函数之后在编译器第一次匹配到这个指令时调用一次,和controller函数类似,通过$injector.invoke来调用指令的工作函数。当AngularJs在DOM中遇到具名的指令时,会去匹配已经注册过得指令,并通过名称在注册过得对象中查找,此时就开始了一个指令的生命周期,指令的生命周期开始于$compile方法并结束与link方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
angular.module('myApp',[])
.directive('myDirective',function(){
return{
restrict:String,
priority:Number,
terminal:Boolean,
template:String or Template function :
function (tElement,tAttrs)(),
replace:Boolean of String,
scope:Boolean or Object,
transclude:Boolean,
controller:String or function(scope,element,attrs,transclude,otherInjectables){},
controllerAs:String,
require: String,
link: function(scope,iElement,iAttrs){},
compile:
function(tElement,tAttrs,transclude){
return {
pre:function(scope,iElement,iAttrs,controller){},
post: function(scope,iElement,iAttrs,controller){}
}
// 或者
return function(){
}
}
}
})

指令定义解释

  1. directive() 方法接受两个参数: name(字符串) 与 function (返回一个对象)。
    当AngularJs 在DOM中遇到具名的指令时,会去匹配已经注册过的指令,并通过名字在注册过的对象中查找。此时,就开始了一个指令的生命周期,指令的生命周期开始于$compile方法并结束于link方法。
  2. restrict : 可选值为 “EACM”
  3. priority :优先级,默认值是0。ngRepeat优先级是1000,在同一个元素上,高优先级的指令优先运行。
  4. terminal : true or false。 用来告诉AngularJs是否停止运行当前元素上比本指令优先级低的指令。但是同当前指令优先级相同的指令还是会与运行。
  5. template :html 或者 函数(参数是 tElement 和 tAttrs,并返回一个代表模板的字符串)
  6. templateUrl: 一个代表外部HTML文件路径的字符串或者 一个可以接受两个参数的函数(tElement 和tAttrs)并返回一个外部HTML文件路径的字符串。 这两种情况模板的URL都将通过AngularJS内置的安全层,特别是$getTrustedResourceUrl,这样可以保护模板不会被不信任的源加载。并且这两情类型在默认情况下都是在后台通过Ajax来请求HTML模板文件, 模板加载时异步的,意味着编译和链接要暂停,等待模板加载完成。
  7. replace : 默认是true 是否模板是被当做子元素插入到调用此指令的元素内部。
  8. scope 参数

    想了解这个参数的使用,必须先了解指令的作用域。在DOM中每个指令调用时都可能会:

    直接调用相同的作用域对象
    从当前作用域对象继承一个新的作用域对象
    创建一个同当前作用域相隔离的作用域对象

    指令中的作用域一定是上面的三种之一。从scope参数的取值就可以理解以上的三种作用域。指令嵌套并不一定意味着需要改变它的作用域。默认情况下,子指令会被赋予访问父DOM元素对应的作用域的能力。

    (1). scope : true or fasle
    scope 默认值是false,意味着和包含着指令的DOM是相同的作用域。 scope的值是true时,意味着会从父作用域继承并创建一个新的作用域对象。内置指令ng-controller的作用就是从父级作用域继承并创建一个新的子作用域,它会创建一个新的从父级作用域继承而来的子作用域。看个demo就轻松懂了…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <div ng-app="myApp"
    ng-init="someProperty = 'some data'"></div>
    <div ng-controller="popCtrl" ng-init="myProperty = 'wow, this is cool'">
    Outside : {{ myProperty }}
    <br/>
    myAnoProperty:{{myAnoProperty}}
    <div my-Inherit-scope-directive ng-init="myAnoProperty = 'wow '">
    </div>
    </div>
    </div>
    angular.module('myApp', [])
    .controller('popCtrl', function($scope) {
    })
    .directive('myInheritScopeDirective',function(){
    return{
    restrict:'A',
    template:"<div>inhi~ {{myProperty}} {{myAnoProperty}}</div>",
    scope:true
    }
    })

    运行结果是

    1
    2
    3
    Outside : wow,this is cool
    myAnoProperty :
    inhi~ wow,this is cool wow

    myInheritScopeDirective 指令中scope值为true,所以会创建从父级popCtrl中继承而来的子级作用域。所以在myInheritScopeDirective指令中的变量 myProperty 和myAnoProperty 都是有值的。但是在myAnoProperty 是在myInheritScopeDirective指令的作用域中进行初始化的,所以在父级作用域是没有办法取到值的。 若是将myInheritScopeDirective指令中的scope取值为false,那么 在popCtrl中的myAnoProperty也是有值的,因为myInheritScopeDirective指令不会创建新的子作用域。

    (2). scope :{} 隔离作用域
    当scope的值不是布尔值,而是变成对象,那么这个指令会创建一个和外层包含的DOM元素对应的作用域相平行的一个隔离作用域。具有隔离作用域的指令最主要的使用场景是创建可复用的组件,组件可以在未知上下文中使用,并且可以避免污染所处的外部作用域或不经意地污染内部作用域。将scope的值取{}空对象,这样指令就无法访问外部作用域了,看了栗子咯…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <div ng-app="myApp"
    ng-init="someProperty = 'some data'"></div>
    <div ng-controller="SecondCtrl" ng-init="myProperty = 'wow, this is cool'">
    Outside : {{ myProperty }}
    <div my-directive >
    </div>
    </div>
    angular.module('myApp', [])
    .controller('SecondCtrl', function($scope) {
    })
    // scope :{} 是独立作用域 只有在自己作用域上的赋值才能使用, 在外层上的作用域并不是父作用域 ,并不能够使用
    .directive('myDirective', function() {
    return {
    restrict: 'A',
    scope: {},
    priority:100,
    template:"<div>hello {{myProperty}}</div>"
    }
    })

    运行结果是

    1
    2
    Outside : wow,this is cool
    hello

    在这里myDirective指令创建了隔离作用域,所以自然myProperty变量是获取不到外面的值的。

从上面可以看出创建一个空的隔离作用域是没有太大意义的,因为没有办法获取外界信息,就没有办法进行交互,所以应该个隔离作用域传递数据,关于数据的传递有三种,即数据的绑定策略有三种: @、=、&。

本地作用域属性:@(or @attr)
@ 可以将本地作用域同DOM 属性的值进行绑定,指令作用域可以使用外部作用域的变量。
双向绑定 : =( or =attr)
= 可以将本地作用域上的属性同父级作用域上的属性进行双向的数据绑定,就像普通的数据绑定一样,本地属性会反映出父数据模型中所发生的改变。
父级作用域绑定 : &(or &=attr)
& 可以对父级作用域进行绑定,以便在器中运行函数,意味着对这个值进行设置时会生成一个指向父级作用域的包装函数。

废话少说,上栗子!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<body ng-controller="bodyCtrl">
<!--my-Url 大小写无所谓 但必须是短线分隔形式-->
<input type="text" name="name" value="" ng-model="a">
<div my-directive baidu-Url="{{a}}" my-Link-Text="{{myLinkText}}"></div>
<!--注意在这里使用的是 a,即绑定的直接是变量值 而不是{{a}}-->
<div my-two-directive baidu-Url="a" >
</div>
<div my-three-directive fun ="show(a)" >
</div>
<script type="text/javascript">
angular.module('myApp', [])
.controller('bodyCtrl',['$scope',function($scope){
$scope.a ="http://baidu.com";
$scope.myLinkText = "baidu";
$scope.show = function (a){
console.log(a);
}
}])
// 指令是形成自己的独立作用域 在使用指令时 ,指令中的scope上的变量 将DOM中同属性的值赋值到自己的 scope变量上。
// 指令也可以有自己的控制器
.directive('myDirective', function() {
return {
restrict: 'AE',
replace: true,// 是否显示自己自定义的指令
scope: {
myUrl: '@baiduUrl',
myLinkText: '@'// @ 绑定是找到属性名相同的直接绑定
},
// 用 \ 来换行
template: '<div>\
<a href="{{myUrl}}">{{myLinkText}}{{myUrl}}</a>\
</div>',
controller:function($scope){
console.log($scope.myUrl);// baidu.com
console.log($scope.baiduUrl);// undefined
}
};
})
.directive('myTwoDirective', function() {
return {
restrict: 'AE',
replace: false,// 是否显示自己自定义的指令
scope: {
myUrl: '=baiduUrl'
},
// 用 \ 来换行
template: '<div>\
{{myUrl}}\
</div>',
controller:function($scope){
console.log($scope.myUrl);// baidu.com
console.log($scope.baiduUrl);// undefined
}
};
})
.directive('myThreeDirective', function() {
return {
restrict: 'AE',
replace: false,// 是否显示自己自定义的指令
scope: {
show: '&fun'// 与 外层作用域进行绑定,以运行其函数
},
// 用 \ 来换行
template: '<div>\
{{myUrl}}\
</div>',
controller:function($scope){
$scope.show();
}
};
})
</script>
</body>

这个这么明显还有注释就不解释啦,嘿嘿。。。犯懒了。。。

引用文献

  1. 《AngularJS权威教程》
文章目录
  1. 1. 内置指令
  2. 2. 指令定义
  3. 3. 指令定义解释
  4. 4. 引用文献