|
| 1 | +# angularJS 6장 |
| 2 | + |
| 3 | +작성자 : 장현웅 |
| 4 | + |
| 5 | +작성일 : 2016-02-15 |
| 6 | + |
| 7 | + |
| 8 | +### 커스텀 디렉티브 구현 |
| 9 | + |
| 10 | + |
| 11 | + |
| 12 | +```html |
| 13 | + |
| 14 | + |
| 15 | +<html ng-app="exampleApp"> |
| 16 | +<head> |
| 17 | + <title>Directives</title> |
| 18 | + <script src="angular.js"></script> |
| 19 | + <link href="bootstrap.css" rel="stylesheet" /> |
| 20 | + <link href="bootstrap-theme.css" rel="stylesheet" /> |
| 21 | + <script> |
| 22 | + angular.module("exampleApp", []) |
| 23 | + .directive("unorderedList", function () { //unorderedList 라는 디렉티브를 선언 |
| 24 | + return function (scope, element, attrs) { |
| 25 | + var data = scope[attrs["unorderedList"]]; //어트리뷰트중 unoderedList 를 불러옴 |
| 26 | + var propertyName = attrs['listName']; |
| 27 | + var propertyPrice = attrs['listPrice']; |
| 28 | + if(angular.isArray(data)) { |
| 29 | + var listElem = angular.element("<ul>"); //불러온 엘레멘트에 하위요소 ul을 생성 |
| 30 | + element.append(listElem); |
| 31 | + console.log(data); |
| 32 | + for(var i = 0 ; i < data.length ; i++){ |
| 33 | + (function(){ //즉시호출함수 |
| 34 | + var index = i; |
| 35 | + var itemElement = angular.element('<li>'); |
| 36 | +
|
| 37 | + listElem.append(itemElement); |
| 38 | +
|
| 39 | + var watcherFn = function(watchScope){ //와쳐생성 |
| 40 | + return watchScope.$eval(propertyPrice, data[index]); |
| 41 | + } |
| 42 | +
|
| 43 | + scope.$watch(watcherFn, function(newValue, oldValue){ |
| 44 | + itemElement.text(newValue); |
| 45 | + }); |
| 46 | + }()); |
| 47 | +
|
| 48 | +
|
| 49 | + } |
| 50 | + } |
| 51 | + } |
| 52 | + }) |
| 53 | + .controller("defaultCtrl", function ($scope) { |
| 54 | + $scope.products = [ |
| 55 | + { name: "Apples", category: "Fruit", price: 1.20, expiry: 10 }, |
| 56 | + { name: "Bananas", category: "Fruit", price: 2.42, expiry: 7 }, |
| 57 | + { name: "Pears", category: "Fruit", price: 2.02, expiry: 6 } |
| 58 | + ]; |
| 59 | +
|
| 60 | + $scope.incrementPrices = function(){ |
| 61 | + for(var i = 0 ; i < $scope.products.length ; i++){ |
| 62 | + $scope.products[i].price++; |
| 63 | + console.log($scope.products[i].price); |
| 64 | + } |
| 65 | + } |
| 66 | + }) |
| 67 | + </script> |
| 68 | +</head> |
| 69 | +<body ng-controller="defaultCtrl"> |
| 70 | + <div class="panel panel-default"> |
| 71 | + <div class="panel-heading"> |
| 72 | + <h3>Products</h3> |
| 73 | + </div> |
| 74 | + <div class="panel-body"> |
| 75 | + <button class="btn btn-primary" ng-click="incrementPrices()"> |
| 76 | + change price |
| 77 | + </button> |
| 78 | + </div> |
| 79 | + <div class="panel-body"> |
| 80 | + <div unordered-list="products" list-name="name" list-price="price | currency"></div> <!--//엘레멘트로 커스텀디렉티브명 선언--> |
| 81 | + </div> |
| 82 | + </div> |
| 83 | +</body> |
| 84 | +</html> |
| 85 | + |
| 86 | +``` |
| 87 | + |
| 88 | +커스텀디렉티브를 구현할 때는 |
| 89 | + |
| 90 | +module.directive 를 이용하여 생성하며 이때 생성될 디렉티브 이름과 생성할 디렉티브를 만들 function을 선언해준다. |
| 91 | +```html |
| 92 | + |
| 93 | + angular.module("exampleApp", []).directive("unorderedList", function () { //unorderedList 라는 디렉티브를 선언 |
| 94 | +``` |
| 95 | + |
| 96 | + |
| 97 | +이후 div태그의 머트리뷰트로 아까 선언한 디렉티브 이름을 선언해준다. 이때 선언하는 방식이 조금다른데 "unorderedList" 이런식으로 대문자를 중간에 껴서 선언했다면 |
| 98 | + |
| 99 | +어트리뷰트를 선언할 때는 "unordered-list" 와 같이 선언해준다. 이유는 태그의 어트리뷰트에는 대소문자 구분이 없기때문에 '-'로 구분하여 대문자라고 인식을 하게 해준다. |
| 100 | + |
| 101 | +```html |
| 102 | + |
| 103 | +<div unordered-list="products"></div> <!--//엘레멘트로 커스텀디렉티브명 선언--> |
| 104 | + |
| 105 | +``` |
| 106 | + |
| 107 | + |
| 108 | +엘레멘트에 선언된 어트리뷰트를 통해 값을 전달하는것도 가능하다. |
| 109 | + |
| 110 | +```html |
| 111 | + |
| 112 | +var propertyName = attrs['listName']; <!--변수에 'name'이라는 문자열이 박힌다--> |
| 113 | + |
| 114 | +<div unordered-list="products" list-name="name"></div> <!--//엘레멘트로 커스텀디렉티브명 선언--> |
| 115 | +``` |
| 116 | + |
| 117 | +이때 list-price="price | currency" 과같이 속성명에 필터를 사용하면 정상적으로 불러와지지 않게된다. |
| 118 | + |
| 119 | +이럴땐 scope.$eval()함수를 써서 정상적인 표현이 가능하다. |
| 120 | + |
| 121 | +```html |
| 122 | + |
| 123 | +var propertyPrice = attrs['listPrice']; |
| 124 | +scope.$eval(propertyPrice,data[i]); //$1.20, $2.42, $2.02 값 출력 |
| 125 | + |
| 126 | +<div unordered-list="products" list-name="name" list-price="price | currency"></div> <!--//엘레멘트로 커스텀디렉티브명--> |
| 127 | + |
| 128 | +``` |
| 129 | + |
| 130 | +price라는 값을 전달받고 그 키에대한 값을 가져온후 필터를 적용한 모습을 볼 수 있다. |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | +####와쳐추가 |
| 135 | + |
| 136 | +와쳐를통해서 값을 실시간으로 데이터변화에 반응하게 하는기능을 추가. |
| 137 | + |
| 138 | +```html |
| 139 | + |
| 140 | +for(var i = 0 ; i < data.length ; i++){ |
| 141 | + (function(){ //즉시호출함수 |
| 142 | + var index = i; |
| 143 | + var itemElement = angular.element('<li>'); |
| 144 | + |
| 145 | + listElem.append(itemElement); |
| 146 | + |
| 147 | + var watcherFn = function(watchScope){ //와쳐생성 |
| 148 | + return watchScope.$eval(propertyPrice, data[index]); |
| 149 | + } |
| 150 | + |
| 151 | + scope.$watch(watcherFn, function(newValue, oldValue){ |
| 152 | + itemElement.text(newValue); |
| 153 | + }); |
| 154 | + }()); |
| 155 | + |
| 156 | + |
| 157 | +} |
| 158 | + |
| 159 | +$scope.incrementPrices = function(){ //버튼을 누를때마다 호출하여 모든값을 1씩증가 |
| 160 | + for(var i = 0 ; i < $scope.products.length ; i++){ |
| 161 | + $scope.products[i].price++; |
| 162 | + console.log($scope.products[i].price); |
| 163 | + } |
| 164 | +} |
| 165 | + |
| 166 | +<button class="btn btn-primary" ng-click="incrementPrices()"> |
| 167 | +``` |
| 168 | + |
| 169 | +버튼을 누를때마다 값을 1씩증가하게 만들고 |
| 170 | + |
| 171 | +와처를 생성하여 값이 변화하면 1씩 증가한 값을 실시간으로 적용 |
| 172 | + |
| 173 | +이때 watcherFn을 선언하고 호출을 하는시점은 for문이 다 돈 이후이기 때문에 i값이 각각 적용이 되질 않음. |
| 174 | + |
| 175 | +따라서 즉시호출함수를 선언하여 index변수를 새로 선언하여 넘겨줘야 재대로 된 결과를 얻을 수 있음. |
| 176 | + |
| 177 | + |
0 commit comments