AngularJS의 조건문은 4가지가 존재한다.
<div ng-switch on="fruits">
<div ng-switch-when="apple">
<!-- fruits값이 apple일 때 해당 태그가 실행됩니다.-->
</div>
<div ng-switch-default>
<!-- code to render the regular video block -->
</div>
</div>
on
에 switch
의 대상이 되는 변수를 적어준다.
<div ng-app="">
<input type="text" ng-model="fruits">
<p>입력한 값: </p>
<div ng-switch="" on="fruits">
<div ng-switch-when="appel">
apple을 입력!
</div>
<div ng-switch-default>
아무것도 입력하지 않음
</div>
</div>
</div>
<div ng-hide="isBlockedMember">
<!-- isBlockedMember가 true값을 가지면 해당 <div>태그는 보이지 않습니다.-->
</div>
<div ng-show="isLogged">
<!-- isLogged가 true값을 가지면 해당 <div>가 보이게 됩니다. -->
</div>
특정 조건에 있어 show/hide를 할 수 있는 directive
이다.
<div>
<spand>isMember:</span>
<select ng-model="isMember">
<option value="true">YES</option>
<option value="false">NO</option>
</select>
<p>isMember : </p>
<div ng-show="isMember=='true'">
회원입니다.
</div>
<div ng-hide="!(isMember=='false')">
회원이 아닙니다.
</div>
</div>
<div ng-class="{block-member: member.isBlocked}">
<!-- member객체의 isBlocked의 값이 true이면 해당 태그에 block-member클래스가 등록됩니다. -->
</div>
css와 함께 태그를 컨트롤하기에 좋음
<div style="width:100%; background-color:#eee">
<span>chang Background color: </span>
<input type="text" ng-model="bgColor" placeholder="red를 입력해보세요.">
<div style="width:200px; height:100px;" ng-class="{'red: bgColor=='red'}">
</div>
</div>
<div ng-if="lastLogged == today">
<!-- 변수의 값이 today와 일치할 때 이 태그가 보여지게 됩니다.-->
</div>
<div ng-if="lastLogged != today">
<!-- 변수의 값이 today와 일치하지 않을 때 이 태그가 보여지게 됩니다. -->
</div>
ng-else
는 존재하지 않는다!!
promise 객체는 약속을 표현하는 자바스크립트 객체이다.
AngularJS에서 $http
,$tiemoute
,$resource
,$route
등 여러 서비스에서 promise객체를 반환한다.
function fetchData(id, cb){
getDataFromServer(id, function(err, result){
if(err){
cb(err, null);
}else{
transformData(result, function(err, transformedResult){
if(err){
cb(err, null);
}else{
saveToIndexDB(result, function(err, savedData){
cb(err, savedData);
});
}
});
}
});
}
위 코드는 콜백지옥이다. promise객체를 사용하면 다음과 같다.
function fetchData(id){
return getDataFromServer(id)
.then(transformData)
.then(saveToIndexDB);
}
then으로 묶어 주면 된다. 코드가 예뻐졌다. 그리고 error
처리도 쉬워진다.
fetchData(1)
.then(function(result){
}, function(error){
// exceptions in transformData, or saveToIndexDB
// will result in this error callback being called.
});
약속을 정의했으면 누군가는 약속을 지키거나 거절해야 한다. 이러한 일을 하는 것이 deferred
객체이다. deferred
객체는 약속을 만들고 만든 약속의 상태를 변경한다.
AngluarJS는 $q.deferred()
를 이용하여 deferred
객체를 생성할 수 있다. (deferred
객체 생성은 곧 Promise
객체 생성이기도 하다.)
deferred
객체는 resolve
,reject
,notify
를 통하여 약속으 지키거나 거절/취소하여 진행 상태를 알려준다.
deferred
객체는 주로 별도의 서비스를 만들고 해당 서비스에서 생성하여 해당 객체의 약속을 반환하는 식으로 많이 사용된다.
angular.module('demo-app', [])
.factory('userService', function($http, $log, $q) {
return {
getUser: function(userId) {
//deferred 객체를 생성한다.
var deferred = $q.defer();
$http.get('/api/users/' + userID)
.success(function(data) {
//요청이 성공하면 약속을 지키고 별도 데이터를 전달한다.
deferred.resolve({
name: data.name,
address: data.address});
}).error(function(msg, code) {
//요청이 실패하면 약속을 취소하고 메시지를 전달한다.
deferred.reject(msg);
$log.error(msg, code);
});
//해당 deferred 객체의 약속을 반환한다.
return deferred.promise;
}
}
});
$q 서비스는 미래에 지켜지거나 지켜지지 않을 여러 약속을 하나의 약속으로 처리할 수 있는 API도 제공한다.
factory('asyncService', function($http, $q) {
return {
loadDataFromTwoReq: function() {
var deferred = $q.defer(),
httpPromise1 = $http.get('/api/req1'),
httpPromise2 = $http.get('/api/req2');
//두 약속을 $q.all 메서드를 이용해 새로운 약속을 만든다.
$q.all(httpPromise1, httpPromise2)
.then(
function(results) {
//두 약속이 모두 지켜지면 asyncService서비스가 반한하는 약속을 지키고 두 약속이 전달하는 결과를 묶은 배열로 전달한다.
deferred.resolve(results)
},
function(errors) {
deferred.reject(errors);
},
function(updates) {
deferred.update(updates);
});
return deferred.promise;
}
};
});
위 코드는 일반적인 콜백 방식으로 작성하게 되면 첫 번째 요청의 성공 콜백에서 다른 요청을 하고 그 요청의 성공 콜백에서 두 요청에 대한 성공 처리를 하는 코드를 작성하게 된다.
하지만!! $q 서비스는 $q.all 메서드를 이용해 약속을 바환하는 여러 비동기적인 일이 병렬적으로 행해지고 있다. 약속을 하나로 묶어 성공/실패 처리를 할 수 있게 해준다.
ng-Repeat
는 기본적으로 필터기능을 지원한다. completed, active, all 세개 버튼을 만들어서 각각을 클릭할때 필터링 로직이 작동하도록 만들어 보자.
<div class="btn-group" role="group" aria-label="...">
<button type="button" ng-click="status='completed'">Completed</button>
<button type="button" ng-click="status='active'">Active</button>
<button type="button" ng-click="status=''">All</button>
</div>
어떤 버튼을 클릭했는지 상태를 저장하는 스코프변수 $scope.status
에 저장한다.
필터에 따라 동적으로 ng-repeat
가 동작해야 한다.
<ul ng-repeat="todo in todos | filter:statusFilter"
버튼을 누를 때 마다 statusFilter
값이 변할 것이다.
이것은 스코프 변수의 변경을 감지하고 그때마다 사용자가 설정한 함수를 실행한다. (주의! 많이 사용하면 메모리 자원을 많이 먹는다.)
// 필터버튼을 클릭하고 status 값이 변경되면 $watch()에 등록한 함수가 동작한다.
$scope.$watch('status', function () {
if ($scope.status === 'completed') { // Completed 클릭시
$scope.statusFilter = {completed: true}; // 필터를 설정한다.
} else if ($scope.status === 'active') { // Active 클릭시
$scope.statusFilter = {completed: false}; // 필터를 설정한다.
} else { // All 클릭시
$scope.statusFilter = {}; // 필터를 해제한다.
}
})
Directive는 템플릿 구조를 모듈화하는 기능이라고 생각하면 쉽다. 간단한 예제를 통해서 Directive 맛만 보자.
<ul ng-repeat="todo in todos | filter:statusFilter" class="list-unstyled">
<li class="todo-item">
<!-- 1. 이 부분이 하나의 todo 를 출력하는 부분이다. -->
<div class="input-group">
<span class="input-group-addon">
<input type="checkbox" aria-label="..." ng-model="todo.completed">
</span>
<input type="text" class="form-control" aria-label="..." ng-model="todo.title">
<div class="input-group-btn">
<button class="btn btn-danger" ng-click="remove(todo.id)">Remove</button>
</div>
</div>
<!-- 2. 위 코드를 아래 한 줄로 바꿔보자!!! Directive를 사용해서 -->
<todo-item todo="todo" remove="remove(todo.id)"></todo-item>
</li>
</ul>
<todo-item>
directive를 만들겠다.
angular.module('todomvc')
.directive('todoItem', function (){
return {
restrict: 'E',
scope: { // 디렉티브 스코프 설정
todo: '=', // 양방향 바인딩
remove: '&' // 참고 바인딩. 함수 설정시 사용함
},
template:
'<div class="input-group">' +
'<span class="input-group-addon">' +
'<input type="checkbox" aria-label="..." ng-model="todo.completed" ng-click="update(todo)">' +
'</span>' +
'<input type="text" class="form-control" aria-label="..."' +
'ng-model="todo.title" ng-blur="update(todo)">' +
'<div class="input-group-btn">' +
'<button class="btn btn-danger" ng-click="remove(todo)">Remove</button>' +
'</div>' +
'</div>'
}
})
Directive를 정의 할때 $scope
객체에 사용할 스코프 변수를 설정할 수 있다. todo
는 데이터인데 출력과 수정을 해야하므로 양방향 바인딩 =
을 사용했다. remove
는 이벤트 핸들러 함수이므로 ckarhdyd &
으로 사용했다.
value | 설명 |
---|---|
E |
Element name |
A |
Attrivute |
C |
Class |
M |
Comment(주석) |
Default 값은 EA
이다.