AngularJS 優雅的自定義指令
阿新 • • 發佈:2019-01-22
學習要點
- 為什麼使用指令
- 建立自定義指令
- 使用jqLite工作
一、為什麼使用自定義指令
NG內建了許多自定義指令,但是它們有時並不能滿足你的要求,這是需要我們建立自定義屬性。
二、自定義指令
接下來,我們來做一個小案例,當滑鼠單擊加價後,列表項自動遞增,當然列表也是通過指令自動新增的,它本就是一個空的div
<!DOCTYPE>
<!-- use module -->
<html ng-app="exampleApp">
<head>
<title>Angluar test</title>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
</head>
<body>
<dlv class="panel panel-default" ng-controller="defaultCtrl">
<div class ="panel-heading">
<h3>Products</h3>
</div>
<div class="panel-body">
<!-- 點選加價,價格遞增 -->
<button type="button" class="btn btn-primary" ng-click="incrementPrices()">加價</button>
</div>
<div class="panel-body">
<!-- 將products資料以一種無序列表的形式展示 -->
<!-- list-property="price | currency" 列表項單位本地化 -->
<div unorderlist="products" list-property="price | currency"></div>
</div>
</dlv>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript">
angular.module("exampleApp", [])
.directive("unorderlist", function () {
// scope 作用域
// element 應用該指令的元素
// attrs 使用該指令的元素的屬性
return function (scope, element, attrs) {
// attrs['unorderlist'] 獲取unorderlist屬性值,這裡為products
// 獲取資料模型值,這裡為scope.products
var data = scope[attrs['unorderlist']];
// 建立一個<ul>標籤元素
var ul = angular.element("<ul>");
// 在應用該指令的元素中新增<ul>
element.append(ul);
// 獲取listProperty屬性值,這裡為price | currency
var expression = attrs['listProperty'];
// 判斷是否為陣列
if (angular.isArray(data)) {
// 遍歷資料模型scope.products
for (var i = 0; i < data.length; i++) {
// 新增閉包,將i傳遞進去
(function (index) {
// 建立一個<li>標籤元素
var li = angular.element("<li>");
// 將<li>標籤新增到<ul>中
ul.append(li);
// 監聽器函式,用$eval計算表示式和data[index]的值
var watcherFn = function (watchScope) {
return watchScope.$eval(expression, data[index]);
}
// 新增$watch監聽器監聽作用域的變化
scope.$watch(watcherFn, function (newValue, oldValue) {
// 更新li的值
li.text(newValue);
})
})(i);
}
}
}
})
.controller("defaultCtrl", function ($scope) {
// 資料模型
$scope.products = [
{ name: "Apples", category: "Fruit", price: 1.20, expiry: 10 },
{ name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 },
{ name: "Pears", category: "Fruit", price: 2.02, expiry: 6 }
];
// 遞增價格
$scope.incrementPrices = function () {
for (var i = 0; i < $scope.products.length; i++) {
$scope.products[i].price++;
}
}
})
</script>
</body>
</html>
解析:
第一步:建立控制器,新增資料模型products和遞增價格incrementPrices()方法
第二步:自定義unorderlist標籤,該標籤的作用是:通過作用域資料模型的值,將其值以無序列表的方式展示出來
第三部:並且在單擊加價按鈕時,無序列表的值會依次遞增
三、使用jqLite工作
NG內建了jqLite,它是JQuery的縮小版
<!DOCTYPE>
<!-- use module -->
<html ng-app="exampleApp">
<head>
<title>Angluar test</title>
<meta charset="utf-8"/>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap-theme.min.css">
</head>
<body>
<dlv class="panel panel-default">
<!-- 使用自定義指令 -->
<ol dome-directive>
<li>Apples</li>
<ul>
<li>Bananas</li>
<li>Cherries</li>
<li>Oranges</li>
</ul>
<li>Pears</li>
<li>Oranges</li>
</ol>
</dlv>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript">
angular.module("exampleApp", [])
.directive("domeDirective", function () {
return function (scope, element, attrs) {
// 找出element元素下所有的li,這裡的element是呼叫者<ol>
var items = element.find("li");
// 要所有的li的font-weight為bold
items.css("font-weight", "bold");
// 遍歷li, 值為Oranges的字型顏色為red,其餘為green
for (var i = 0; i < items.length; i++) {
if (items.eq(i).text() == "Oranges"){
items.eq(i).css("color", "red");
} else {
items.eq(i).css("color", "green");
}
}
// 打印出li的長度和字型顏色
console.log("Items length : " + items.length);
console.log("Color: " + items.css("color"));
}
})
</script>
</body>
</html>
解析:
第一步:自定義控制器,定義資料模型names
第二步:自定義指令,功能是將使用指令的元素下的所有li找出,並且更加值的不同賦給字型不同的顏色
第三步:在檢視中呼叫並且使用指令