<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AngularJS 指令</title>
<script src="../js/jquery-2.1.3.min.js"></script>
<script src="../js/angular.min.js"></script>
</head>
<body>
<!--
ng-app 指令告诉 AngularJS,<div> 元素是 AngularJS 应用程序 的"所有者"。
{{ firstName }} 是通过 ng-model="firstName" 进行同步。
ng-app 指令定义了 AngularJS 应用程序的 根元素。
ng-app 指令在网页加载完毕时会自动引导(自动初始化)应用程序。
稍后您将学习到 ng-app 如何通过一个值(比如 ng-app="myModule")连接到代码模块。
ng-init 指令为 AngularJS 应用程序定义了 初始值。
通常情况下,不使用 ng-init。您将使用一个控制器或模块来代替它。
-->
<!--<div ng-app="" ng-init="firstName='Json'">
<p>在输入框中尝试输入:</p>
<p>姓名:<input type="text" ng-model="firstName"></p>
<p>你输入的为: {{ firstName }}</p>
</div>-->
<!--
在下一个实例中,两个文本域是通过两个 ng-model 指令同步的:
ng-model 指令 绑定 HTML 元素 到应用程序数据。
ng-model 指令也可以:
为应用程序数据提供类型验证(number、email、required)。
为应用程序数据提供状态(invalid、dirty、touched、error)。
为 HTML 元素提供 CSS 类。
绑定 HTML 元素到 HTML 表单。
-->
<!--<div ng-app="" ng-init="quantity=1;price=5">
<h2>价格计算器</h2>
<p>数量:<input type="text" ng-model="quantity"></p>
<p>价格:<input type="text" ng-model="price"></p>
<p><b>总价:</b>{{quantity * price}}</p>
</div>-->
<!--
ng-repeat 指令会重复一个 HTML 元素:
ng-repeat 指令对于集合中(数组中)的每个项会 克隆一次 HTML 元素
-->
<!--<div ng-app="" ng-init="names=['Json', 'Lucy', 'Andy', 'Kite']">
<p>使用 ng-repeat 来循环数组</p>
<ul>
<li ng-repeat="name in names">{{name}}</li>
</ul>
</div>-->
<!--ng-repeat 指令用在一个对象数组上:-->
<!--<div ng-app="" ng-init="names=[
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}]">
<p>循环对象:</p>
<ul>
<li ng-repeat="name in names">{{name.name + " " + name.country}}</li>
</ul>
</div>-->
<!--创建自定义的指令-->
<!--
除了 AngularJS 内置的指令外,我们还可以创建自定义指令。
你可以使用 .directive 函数来添加自定义的指令。
要调用自定义指令,HTML 元素上需要添加自定义指令名。
使用驼峰法来命名一个指令, runoobDirective, 但在使用它时需要以 - 分割, runoob-directive
你可以通过以下方式来调用指令:
元素名
属性
类名
注释
-->
<!--
元素名方式|属性方式(默认)
replace 参数为 true:只会将标签名字替换掉,其他属性仍然保留 如:<h1 id="not_del sec" class="sec_c">自定义指令!</h1>
如果 restrict 是 "A",也只是替换掉原来标签的名称,而属性还是会保留 如:<h1 id="sec" class="sec_c" runoob-directive="">自定义指令!</h1>
-->
<div ng-app="myApp" ng-controller="myCtrl">
<runoob-directive id="not_del"></runoob-directive>
<!--<div runoob-directive></div>-->
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function ($scope) {
$scope.test = "test";
});
app.directive("runoobDirective", function() {
return {
//restrict: "AE", //Default
replace: true,//是否替换掉页面原先定义好的标签,true: 替换|false:不替换,默认为 false
template : "<h1 id='sec' class='sec_c'>自定义指令!</h1>",
link: function (scope, jqEle, attrs) {//加载完成后调用,还可以再对 template 进行修改
console.log(scope);
console.log(jqEle);//[h1#not_del sec.sec_c, context: runoob-directive#not_del]
jqEle.css("color", "red");
console.log(attrs);//mc {$attr: Object, $$element: n.fn.init(1), id: "not_del sec", class: "sec_c"}
//$(attrs.$$element).css("color", "red");
}
};
});
</script>
</div>
<!--
定义指令,执行不同的操作
-->
<!--<div ng-app="myApp" ng-controller="myCtrl">
<div enter="msgLoading()">数据加载中</div>
<div enter="deleteConfirm()">删除数据</div>
</div>
<script>
angular.module("myApp", []).controller("myCtrl", function ($scope) {
$scope.msgLoading = function () {
alert("数据加载中...");
};
$scope.deleteConfirm = function () {
alert("您确认需要删除吗?");
};
}).directive("enter", function () { //默认使用 E, template 为空
return function (scope, jqEle, attrs) {
jqEle.mouseenter(function () {
scope.$apply(attrs.enter);
});
}
});
</script>-->
<!--类名方式-->
<!--<div ng-app="myApp">
<div class="runoob-directive"></div>
<script>
var app = angular.module("myApp", []);
app.directive("runoobDirective", function() {
return {
restrict: "C",
template : "<h1>自定义指令!</h1>"
};
});
</script>
</div>-->
<!--注释方式-->
<!--<div ng-app="myApp">
<!– directive: runoob-directive –>
<script>
var app = angular.module("myApp", []);
app.directive("runoobDirective", function() {
return {
restrict : "M",
replace : true,
template : "<h1>自定义指令!</h1>"
};
});
</script>
<p><strong>注意:</strong> 我们需要在该实例添加 <strong>replace</strong> 属性, 否则评论是不可见的。</p>
<p><strong>注意:</strong> 你必须设置 <b>restrict</b> 的值为 "M" 才能通过注释来调用指令。</p>
</div>-->
<!--
限制使用
你可以限制你的指令只能通过特定的方式来调用。
通过添加 restrict 属性,并设置只值为 "A", 来设置指令只能通过属性的方式来调用:
restrict 值可以是以下几种:
E 作为元素名使用
A 作为属性使用
C 作为类名使用
M 作为注释使用
restrict 默认值为 EA, 即可以通过元素名和属性名来调用指令。
-->
<!-- <div ng-app="myApp">
<div runoob-directive></div>
<script>
var app = angular.module("myApp", []);
app.directive("runoobDirective", function () {
return {
restrict: "A", //区分大小写
template: "<h1>自定义指令!</h1>"
}
})
</script>
</div>-->
<!--<div ng-app="myApp" ng-controller="myCtrl">
<h3 ng-bind="Now"></h3>
<h3 ng-bind="NowTime"></h3>
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function ($scope, $interval) {
var now = new Date(); //获取时间,只能在 controller 里面,不能在 ng-init 里面初始化。
$scope.Now = now.getHours() + ":" + now. getMinutes() + ":" + now.getSeconds();
(function () {
setInterval(function () {
$scope.$apply(function () {//需要手动调用 $apply() 函数,将变化的值映射到页面
now = new Date();
$scope.Now = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds()
})
}, 1000);
})();
//第二种:angular js 内部的 service: $interval 对应了 JS window.setInterval 函数。
$scope.NowTime = new Date().toLocaleTimeString();
$interval(function () {
$scope.NowTime = new Date().toLocaleTimeString();
}, 1000);
});
</script>-->
<!--<div ng-app="myApp" ng-controller="DirectiveController">
<p>姓名: <input type="text" ng-model="name"/> <br/></p>
<!–<first/>–>
<!–<second/><!–继承父级作用域 name–>–>
<!–<third/><!–无法取得 name–>–>
<!–<fourth/><!–使用自己作用域的 name–>–>
<fifth/>
<script>
angular.module('myApp', []).directive('first', [ function(){
return {
// scope: false, // 默认值,共享父级作用域
// controller: function($scope, $element, $attrs, $transclude) {},
restrict: 'AE', // E = Element, A = Attribute, C = Class, M = Comment
template: 'first name:{{name}}',
};
}]).directive('second', [ function(){
return {
scope: true, // 继承父级作用域并创建指令自己的作用域
// controller: function($scope, $element, $attrs, $transclude) {},
restrict: 'AE', // E = Element, A = Attribute, C = Class, M = Comment
//当修改这里的name时,second会在自己的作用域中新建一个name变量,与父级作用域中的
// name相对独立,所以再修改父级中的name对second中的name就不会有影响了
template: 'second name:{{name}}',
};
}]).directive('third', [ function(){
return {
scope: {}, // 创建指令自己的独立作用域,与父级毫无关系
// controller: function($scope, $element, $attrs, $transclude) {},
restrict: 'AE', // E = Element, A = Attribute, C = Class, M = Comment
template: 'third name:{{name}}',
};
}]).directive('fourth', [ function(){
return {
scope: {}, // 创建指令自己的独立作用域,与父级毫无关系
controller: function($scope, $element, $attrs, $transclude) {
$scope.name = "Four"
},
restrict: 'AE', // E = Element, A = Attribute, C = Class, M = Comment
template: 'four name:{{name}}',
};
}]).directive('fifth', [ function(){
return {
scope: true, // 创建指令自己的独立作用域,与父级毫无关系
controller: function($scope, $element, $attrs, $transclude) {
$scope.name = "Five"
},
restrict: 'AE', // E = Element, A = Attribute, C = Class, M = Comment
template: 'fifth name:{{name}}', //优先使用自己作用哉的变量
};
}])
.controller('DirectiveController', ['$scope', function($scope){
$scope.name="mike";
}]);
</script>
</div>-->
<!--<div ng-app="myApp">
<food apple banana orange>food</food>
<br>
<!–<food apple>apple</food> //不能定义多个–>
</div>
<script>
angular.module("myApp", []).directive("food", function () {
return {
restrict: "E",
controller: function ($scope) {//指向下面的 foodCtrl
$scope.food = [];
this.addApple = function () {
$scope.food.push("apple");
};
this.addBanana = function () {
$scope.food.push("banana");
};
this.addOrange = function () {
$scope.food.push("orange");
};
},
link: function (scope, jqEle, attrs) {
jqEle.click(function () {
console.log(scope.food);
});
}
}
}).directive("apple", function () {
return {
require: "food",//这里相当于继承 food 标签,两者相结合才能使用
link: function (scope, jqEle, attrs, foodCtrl) {
foodCtrl.addApple();
}
}
}).directive("orange", function () {
return {
require: "food",
link: function (scope, jqEle, attrs, foodCtrl) {
foodCtrl.addOrange();
}
}
}).directive("banana", function () {
return {
require: "food",
link: function (scope, jqEle, attrs, foodCtrl) {
foodCtrl.addBanana();
}
}
});
</script>-->
</body>
</html>
指令的选项
选项 | 说明 |
---|---|
restrict | 字符串。可选参数,指明指令在DOM里面以什么形式被声明,默认为A(属性);(可取值:A C M E ) |
priority | 数值。可选参数,指明指令的优先级,若在单个DOM上有多个指令,则优先级高的先执行,如果优先级相同,则执行顺序是不确定的。默认值0 |
terminal | true/false; 可选参数,若设置为true,则表示当前的priority将会成为最后一组执行的directive。任何directive与当前的优先级相同的话,他们依然会执行,但顺序是不确定。优先级低于此指令的其他指令则无效,不会被调用。 |
template | 可选参数,字符串(html代码)或者函数(tElement,eAttrs); |
templateUrl | 可选参数,与template基本一致,但模版通过指定的url进行加载。因为模版加载是异步的,所以compilation、linking都会暂停,等待加载完毕后再执行。可以先缓存模板来提高速度(可以使用ng-template或$templateCache来缓存模板) |
templateNamespace | 可选参数,默认值为’html’。’html’ -模板中所有的根节点都是html。根节点也可能是最高级别的的元素,例如<svg>或者<math>,’svg’ - 根节点是svg元素,’math’ - 根节点是math元素 |
replace | 可选参数;true/false;false表示模板会被当作子元素插入到调用此指令的元素内部 |
scope | 可选参数;可取值:true/false 或者一个对象, |
transclude | 可选参数; true/false; |
controller | 可选参数。字符串或者函数;函数中 可以使用$scope,$element,$attrs,$transclude;可复用 |
link | 可选参数。函数。当前指令内部定义行为;方法参数:scope jqEle attrs 如果require是true的话 ,还有另一个参数controller |
controllerAs | 可选参数。字符串,设置控制器的别名 |
require | 可选参数。字符串或者数组。require会将控制器注入到其值所指定的指令中,并作为当前指令的链接函数的第四个参数。 |
compile | 可选参数。对象或者函数 |