原文: www.jianshu.com/p/d55293715…javascript
选这本书就是由于朋友们都推荐这本, 并且讲的还不错, 最重要的是他们有资源, O(∩_∩)O哈哈~html
首先介绍一下本书中关于指令的知识结构:java
用过HTML的都知道, 每每在实现一些特殊功能的时候, 原有的HTML标签并不彻底能知足设计要求, 这时候指令就派上用场了; 指令本质上就是扩展一些自定义的HTML元素以实现一些特定的功能;git
AngularJS事实上也是在原生JS的基础上进行一些扩展和优化, 天然就会包括一些自定义的内置指令; 除了form和a等一些重载了原生的HTML元素, 其余的内置指令一般以ng做为前缀; 这样作的目的也是对原生的一种优化, 好比经常使用的href指令, 不管里面的连接是可用仍是, 不可用的, 当调用href的时候, 就会直接返回调用结果; 而ng-href指令则是当里面的表达式调用而且返回一个值的时候才开启, 不然会是一个禁用状态; 固然既然人家官方用ng这个前缀, 你就不要跟人家抢了, 换一个, 你们和谐一点儿;github
有网友总结了一下AngularJS的内置指令, 一共有63个;数组
简单介绍一下form指令:app
<form>
First name:</br>
<input type="text" name="firstname" value="huo">
<br>
Last name:</br>
<input type="text" name="lastname" value="yu">
<br><br>
<input type="submit" value="Submit">
</form>复制代码
效果图:框架
要注意一下几点:ionic
本书中对指令的定义是在特定DOM元素上运行的函数, 指令能够扩展这个元素的功能;
在Angular中是经过directive()这个模块来定义指令的;而directive()能够接受两个参数:函数
angular.application('myApp', [])
.directive('myDirective', function() {
// 一个指令定义对象
return {
// 经过设置项来定义指令, 在这里进行填写
};
});复制代码
在HTML中调用就行:<div my-directive></div>复制代码
这些选项能够单独使用, 也能够混合使用;
2.2 优先级(数值型)
因为考虑到性能问题, ngRepeat被设置成全部内置指令中优先级最高的; 固然若是两个元素的优先级同样, 会执行先声明的那个;
2.3 terminal(布尔型)
它用来告诉AngularJs中止运行当前元素上比本指令优先级低的指令, 但当优先级相同的状况仍是会运行;
例如:ngView和ngIf, ngIf的优先级略高于ngView, 若是ngIf表达式为true, ngView就能够被正常执行; 但若是ngIf的表达式为false, ngView就不会被执行;
2.4 template(字符串或函数)
template参数必须被设置成如下两种形式之一:
2.5 templateUrl(字符串或函数)
templateUrl参数能够是如下形式:
2.6 replace(布尔型)
replace是个可选参数, 默认为false; 当设置为true后
.directive('someDirective', function() {
return {
replace: true
template: '<div>looking for something<div>'
};
});复制代码
输出结果为:
<div>looking for something<div>复制代码
2.7 scope参数(布尔型或对象)
scope参数有三种取值方式;
2.7.1 false(默认值)
直接使用父scope, 内部并无一个新的scope,它和指令之外的代码共享同一个scope。
①指令
app.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
templateUrl: '../templates/my_template.html',
scope: false, // 默认值
controller: null
}
});复制代码
②指令模板(my_template.html)
<div>
<!--这里ng-model绑定的input,就是父scope的变量input-->
<p>自定义指令scope:<input type="text" ng-model="input"></p>
<p>结果:{{input}}</p>
</div>复制代码
③指令的使用(index.html)
<body ng-app="scopeTest" ng-controller="scopeTestStr">
<p>父scope:<input type="text" ng-model="input"></p>
<!--自定义指令-->
<my-directive></my-directive>
</body>复制代码
效果以下:
2.7.2 true(继承父scope)
当设置为true的时候, 会从父做用域继承并建立一个新的做用域对象;
参照值为false的状况, 只是将值改成true; 效果以下:
2.7.3 { }
建立一个新的"隔离"scope,但仍可与父scope通讯;
隔离的scope,一般用于建立可复用的指令,也就是它不用管父scope中的model。然而虽说是“隔离”,但一般咱们仍是须要让这个子scope跟父scope中的变量进行绑定。绑定的策略有3种:
①@ 单项绑定
<body ng-app="scopeTest">
<!--外部scope-->
<p>父scope:<input type="text" ng-model="input"></p>
<!--内部隔离scope-->
<my-directive my-text="{{input}}"></my-directive>
<script> var app = angular.module('scopeTest', []); app.directive('myDirective', function () { return { restrict: 'E', replace: true, template: '<p>自定义指令scope:<input type="text" ng-model="myText"></p>', scope: { myText: '@' } } }); </script>
</body>复制代码
效果图:
②= 双向绑定
<body ng-app="scopeTest">
<!--外部scope-->
<p>父scope:<input type="text" ng-model="input"></p>
<!--内部隔离scope-->
<!--注意这里,由于是双向绑定,因此这里不要“{{}}”这个符号-->
<my-directive my-text="input"></my-directive>
<script> var app = angular.module('scopeTest', []); app.directive('myDirective', function () { return { restrict: 'E', replace: true, template: '<p>自定义指令scope:<input type="text" ng-model="myText"></p>', scope: { myText: '=' // 这里改为了双向绑定 } } }); </script>
</body>复制代码
效果图:
③& 内部scope的函数返回值和外部scope绑定
<body ng-app="scopeTest">
<!--外部scope-->
<p>父scope:<input type="text" ng-model="input"></p>
<!--内部隔离scope-->
<!--注意这里,函数名字也要用 连字符命名法-->
<my-directive get-my-text="input"></my-directive>
<script> var app = angular.module('scopeTest', []); app.directive('myDirective', function () { return { restrict: 'E', replace: true, template: '<p>结果:{{ getMyText() }}</p>', scope: { getMyText: '&' // 这里改为了函数返回值的绑定 } } }); </script>
</body>复制代码
效果图:
2.8 transclude(布尔型)
默认为false; 只有当你但愿建立一个能够包含任意内容的指令的时候才会为true; 代码以下所示:
app.directive('myDirective', function() {
return {
restrict: 'AE',
transclude: true,
template: "<div> hellow angular ! <div ng-transclude></div></div>"
}
});复制代码
2.9 controller(字符串或函数)
指令内部的controller, 暴露一些public方法给内部指令使用;
①字符串;
angular.module('myApp', [])
.directive('myDirective', function() {
restrict: 'A', // 始终须要
controller: 'SomeController'
})
// 在应用中其余地方定义该控制器
angular.module('myApp')
.controller('SomeController', function($scope, $element, $attrs, $transclude) {
// 控制器逻辑
});复制代码
②函数
能够是指令内部经过匿名构造函数的方式来定义一个内联的控制器;
angular.module('myApp',[])
.directive('myDirective', function() {
restrict: 'A',
controller:
function($scope, $element, $attrs, $transclude) {
// 控制器逻辑
}
});复制代码
如今你也能够知道, 控制器中还有其余一些特殊的服务能够注入到指令中, 这些服务有:
在控制器内部操做DOM和angular.js风格相悖的作法, 但经过链式函数就能够实现这个需求; 例如在compile参数中使用transcludeFn是推荐的作法;
本文提供了一个添加超连接的例子:
angular.module('myApp')
.directive('link', function() {
return {
restrict: 'EA',
transclude: true,
controller:
function($scope, $element, $transclude, $log) {
$transclude(function(clone) {
var a = angular.element('<a>');
a.attr('href', clone.text());
a.text(clone.text()); 8 $log.info("Created new a tag in link directive");
$element.append(a);
});
}
};
});复制代码
link函数能够与控制器指令的控制器互换; 控制器用来提供指令间的复用行为, 但连接函数只能在当前内部指令中定义行为且没法在指令间复用;
link函数能够将指令互相隔离, 而controller则定义可复用的行为;
下面附一张link函数与compile函数的比较图:
2.10 require(字符串或数组)
字符串或数组的值会是当前指令做用域中使用的指令名称, 即用来调用暴露的内部方法;
对于指令的学习, 书中提供了内部原理, 固然光这些仍是远远不够, 附上一个第三方指令库, 看看源码, 体验一下别人是怎么写的;
AngularUI