ng-app , ng-controller, ng-repeat, ng-src 등은 이미 구현되어 있는 directives이다.
directives에 대해서 무엇을 일반화 시킬 수 있을까?
Directives는 HTML elements에 동작을 결합한다.
앱이 실행되면, AngularJS는 각 HTML element가 directives를 찾을 수 있도록 안내한다.
그 중 하나를 발견하면, AngularJS는 그 동작(scope를 붙이거나 배열 반복 등)을 수행하도록 한다.
app.directive('appInfo', function(){
return{
restrict: 'E',
scope:{
info: '='
},
templateUrl: 'js/directives/appInfo.html'
}
});
브라우저에세 새로운 HTML 요소 <app-info> 를 알려주기 위한 코드를 작성하고, view에서 각 app's detail을 보여주기 위해서 이 코드를 사용한다.
appInfo.js 파일에 새로운 directive를 만들기 위해서 app.directive 를 사용했고, 디렉티브의 이름을 appInfo 라고 명명했다.
이것은 세 개의 오브젝트를 반환한다:
1. restrict 는 디렉티브가 view에서 어떻게 사용될지를 구체적으로 명시한다. 'E' 는 이것이 새로운 HTML element로서 사용될 것이라는 것을 의미한다.
2. scope는 우리가 info 라는 이름의 속성(attribute)을 통해서 디렉티브에 정보를 전달하도록 지정한다. '='는 디렉티브에게 아래처럼 생긴 <app-info> element에서 info라는 attribute를 찾아보라고 말한다.
<app-info info="shutterbugg"></app-info>
info 안에 있는 데이터는 templateURL에 있는 템플릿에서 사용할 수 있게 된다.
3. templateUrl은 HTML을 scope.info 의 데이터를 보여주기 위해 HTML을 가리한다.
<img class="icon" ng-src="{{info.icon}}">
<h2 class="title">{{info.title}}</h2>
<p class="developer">{{info.developer}}</p>
<p class="price">{{info.price | currency}}</p>
js/directives/appInfo.html을 보면, 우리는 제목이나 가격 같은 app에 대한 세부 정보를 보여주기 위한 HTML을 정의한다. 이 때, 데이터를 보여주기 위해서 표현식이나 필터를 이용하게 된다.
<body ng-app="AppMarketApp"> <div class="header"> <div class="container"> <h1>App Market</h1> </div> </div> <div class="main" ng-controller="MainController"> <div class="container"> <div class="card"> <app-info info="move"></app-info> <app-info info="shutterbugg"></app-info> <app-info info="gameboard"></app-info> </div> </div> </div> <!-- Modules --> <script src="js/app.js"></script> <!-- Controllers --> <script src="js/controllers/MainController.js"></script> <!-- Directives --> <script src="js/directives/appInfo.js"></script> </body>
그런 다음 index.html에서 새로운 HTML 요소 <app-info>를 새로운 디렉티브로 사용한다. 이것들을 사용하기 위해서, controller의 scope($scope.shutterbugg)를 <app-info> 의 요소인 info 속성 안에 오브젝트로 전달한다.
app.controller('MainController', ['$scope', function($scope) {
$scope.move = {
icon: 'img/move.jpg',
title: 'MOVE',
developer: 'MOVE, Inc.',
price: 0.99
};
$scope.shutterbugg = {
icon: 'img/shutterbugg.jpg',
title: 'Shutterbugg',
developer: 'Chico Dusty',
price: 2.99
};
$scope.gameboard = {
icon: 'img/gameboard.jpg',
title: 'Gameboard',
developer: 'Armando P.',
price: 1.99
};
}]);
<div ng-repeat="product in products">
<img ng-src="{{product.cover}}">
<p class="title">{{ product.name }}</p>
<div>
디렉티브는 AngularJS의 핵심 기능이다. 여태까지 정적인 콘텐츠를 간단히 보여주는 커스텀 디렉티브를 알아보았는데, 디렉티브는 그것보다 더 많은 일들을 할 수 있다. 즉, 디렉티브는 상호 작용하도록 동작하게 할 수도 있다.
이전까지 디렉티브의 세 가지 옵션, restrict, scope, templateUrl 에 대해서 알아봤는데, 디렉티브에는 추가적으로 link라는 옵션도 있다. link는 사용자 동작에 응답하는 대화식 디렉티브를 만드는데 사용되며, 세 가지 입력을 필요로 한다.
1. scope 는 디렉티브의 스코프를 의미한다. 어떤 새로운 $scope에 연결된 자산이라도 디렉티브의 템플릿에서 이용이 가능하다.
2. element는 디렉티브의 HTML 요소를 의미한다.
3. attr은 요소(element)의 속성을 포함시킨다.
link 함수 내부에는 scope.buttonText="install", scope.installed = false 등의 형태로 속성을 가질 수 있으며, scope.download = function(){} 과 같이 function을 가질수도 있다.
Directives 는 자체적으로 내장된, 대화형 구성요소를 만들 수 있는 강력한 방법이다. HTML의 상단에 레이어 형태로 상호 작용을 추가하는 jQuery완 달리, AngularJS는 상호작용을 HTML의 기본 구성 요소로 다룬다.