Upload
jeado-ko
View
15.896
Download
4
Embed Size (px)
DESCRIPTION
XECon+PHPFest 2014에서 발표한 자료. https://xecon2014.xpressengine.com/
Citation preview
jQuery 개발자에서
AngularJS 개발자 되기
고재도
GDG Korea WebTech
2014.11.08 Session 2-5 XECon + PHPFest 2014
• GDG Korea WebTech 운영자
• 표즌프레임워크 오픈 커미터 리더 4기• 시작하세요 AngularJS 프로그래밍 집필
• kt 소프트웨어 개발센터, IoT 플랫폼 개발
고재도
무엇을 위해?
고통을 덜어주기 위해
<!doctype html><html><head> <script src="jquery.js"></script></head><body> <span id="q"></span> <script> $( "span#q" ).html( "1 + 2 = 3" ); </script></body></html>
<!doctype html><html ng-app><head> <script src="angular.js"></script></head><body> <span>1 + 2 = {{ 1+2 }}</span></body></html>
https://docs.angularjs.org/guide/introduction
http://jquery.com/
JavaScript Library
JavaScript Framework
제이쿼리로 MVC 코드
<div id="search-panel"><label>부서</label><select class="dept-dropbox">
<option value="">선택</option></select><label>직급</label><select class="pos-dropbox">
<option value="">선택</option></select><button id="sFind">검색</button>
</div><div id="gridPanel">
<table class="table table-bordered table-hover"><thead>
<tr><td>사번</td><td>이름</td><td>부서</td>
</tr></thead><tbody></tbody>
</table></div>
jQuery 코드
var $deptDropbox = $("#search-panel .dept-dropbox"),$posDropbox = $("#search-panel .pos-dropbox"),$tableBody = $("#gridPanel tbody"),gridColumn = ["userId", "userNm", "deptCd"];
makeDropBox($deptDropbox, [{ cdDetailNo: '001', cdDetailName: '부서A'},{ cdDetailNo: '002', cdDetailName: '부서B'}]);
makeDropBox($posDropbox, [{ cdDetailNo: '001', cdDetailName: '사원'},{ cdDetailNo: '002', cdDetailName: '대리'}
]);
$("#sFind").click(function() { $.ajax("user.json",{ data : { deptCode : $deptDropbox.val(), posCode : $posDropbox.val() } })
.success(function(data){ buildTable($tableBody, data);
});});
jQuery 코드
function makeDropBox(dropbox, listData){ var option = $("<option>");
$.each(listData, function(i,val) { dropbox.append( $('<option></option>').val(val.cdDetailNo).html(val.cdDetailName) );});
}
function buildTable(el, listData){var list = "";if(listData){
for(var i = 0, length = listData.length; i < length; i++) {list += "<tr>";for(var j = 0, length2 = gridColumn.length; j < length2; j++) {
list += "<td>";list += listData[i][gridColumn[j]] || " ";list += "</td>";
}list += "</tr>";}
} el.append(list);}
jQuery 코드
<body ng-controller="userMgtCtr"><div>
<label>부서</label><select ng-model="sObj.deptId" ng-options="d.deptId as d.deptNm for d in deptList">
<option value="">선택</option></select><label>직급</label><select ng-model="sObj.posId" ng-options="p.posId as p.posNm for p in posList">
<option value="">선택</option></select><button ng-click="find(sObj)">검색</button>
</div><div>
<table class="table table-bordered table-hover"><thead>
<tr><td>사번</td><td>이름</td><td>부서</td>
</tr></thead><tbody>
<tr ng-repeat="user in userList"><td>{{user.userId}}</td><td>{{user.userNm}}</td><td>{{user.deptCd}}</td>
</tr></tbody>
</table></div>
</body>
AngularJS 코드
angular.module(‘mvcApp’,[]).controller('userMgtCtr', [‘$scope','$http', function ($scope, $http) {
$scope.sObj={deptId:'',posId:''};
$scope.deptList = [{ deptId: '001', deptNm: '부서A'},{ deptId: '002', deptNm: '부서B'}
];
$scope.posList = [{ posId: '001', posNm: '사원'},{ posId: '002', posNm: '대리'}
];
$scope.find = function (sObj) {$http({
method: 'GET', url: 'user.json',params: { deptId: sObj.deptId, posId: sObj.posId }
}).success(function(data, status, headers, config) {
$scope.userList = data;});
};}]);
AngularJS 코드
MVC 구조
차이점을 아시겠나요?
IMPERATIVE
DECLARATIVE
<input id="toggleShowHide" type="checkbox"><div id="specialParagraph">위의 체크박스를 클릭하면 보시는 내용은 숨겨질 것입니다.</div><script type="text/javascript">
$(function() {function toggle() { var isChecked = $('#toggleShowHide').is(':checked'); var specialParagraph = $('#specialParagraph'); console.log(isChecked); if (!isChecked) { specialParagraph.show(); } else { specialParagraph.hide(); }}
$('#toggleShowHide').change(function() { toggle();});
toggle();});
</script>
<input ng-model="showSpecial" type="checkbox"><div ng-hide="showSpecial">위의 체크박스를 클릭하면 보시는 내용은 숨겨질 것입니다.</div>
양방향 데이터 바인딩
템플릿 뷰데이터
<ul> <li ng-repeat="user in userList"> <input type="number" ng-model="user.age">
{{user.name}} </li></ul><div> 나이 합계 : {{userList[0].age + userList[1].age}}</div>
+ =
$scope.userList = [ {name:'제이', age:25}, {name:'블레어', age:28}];
템플릿 뷰데이터
<ul> <li ng-repeat="user in userList"> <input type="number" ng-model="user.age">
{{user.name}} </li></ul><div> 나이 합계 : {{userList[0].age + userList[1].age}}</div>
+ =
사용자 화면 값 변경
$scope.userList = [ {name:'제이', age:25}, {name:'블레어', age:28}];
템플릿 = 표현식 + 지시자
표현식
예제
•{{ 1+2 }}
•{{ 3*10 | currency }}
•{{ user.name }}
특징
•Scope 객체 기준으로 속성들을 검사한다. (window 로부터가 아니라…)
•Null 에러를 무시한다. ({{a.b.c}} vs {{((a||{}).b||{}).c}})
•조건문은 올 수 없다.
•필터들과 함께 쓰인다. ({{ 3*10 | currency }})
.
Angular가 제대로 실행 되지 않을 경우 브라우저에 {{ 표현식 }}이 그대로 보이게 된다. ng-bind를 이용하면 이를 방지할 수 있다.
<body> <div ng-controller="sampleCtrl"> 고객 목록
<ul> <li ng-repeat="user in userList"> <input type="number" ng-model="user.age"> {{user.name}} </li> </ul> <div>나이 합계 : {{userList[0].age + userList[1].age}}</div> </div></body>
$scope.userList = [ {name:'제이', age:25}, {name:'블레어', age:28}];
반복적인 데이터 표현 템플릿
<input type="radio" ng-model="color" value="red"> 빨간색 <br><input type="radio" ng-model="color" value="green"> 녹색 <br>
<div ng-switch="color"><div ng-switch-when="red" class="box red"></div><div ng-switch-when="green" class="box green"></div><div ng-switch-default="" class="box black"></div></div>
<div>약관에 동의: <input type="checkbox" ng-model="checked" ng-init="checked=false"><br>동의하면 다음으로 진행됩니다.<button ng-if="checked">다음</button></div>
조건적인 데이터 표현 템플릿
<form name="sampleForm" ng-init="name = '철수'">이름 : <input type="text" name="name" ng-model="name" ng-maxlength="3" ng-required="true"><span class="error" ng-show="sampleForm.name.$error.required">필수입력</span><br>핸드폰 번호: <input type="text" name="tel" ng-model="tel" ng-pattern="/^\d{3}-\d{3,4}-\d{4}$/"><span class="error" ng-show="sampleForm.tel.$error.pattern"> 000-0000-0000</span>
</form>
폼과 유효성 검사 템플릿
<script type=“text/javascript">function mainCtrl($scope){
$scope.message = "";
$scope.eventCnt = 0;
$scope.handleEvt = function(message) { $scope.message = message; $scope.eventCnt++;
}}
</script><body ng-controller="mainCtrl">
<div class="box" ng-click="handleEvt('박스 클릭됬다.')">click</div><div class="box" ng-mousedown="handleEvt('박스 mousedown 이벤트 발생.')">mousedown</div><div class="box" ng-mouseenter="handleEvt('박스 mouseenter 이벤트 발생.')">mouseenter</div><div class="box" ng-mousemove="handleEvt('박스 mouseenter 이벤트 발생.')">mousemove</div>change : <input type="text" ng-model="inputText" ng-change="handleEvt('입력 박스의 값이 변경되
었다.')">keydown : <input type="text" ng-model="inputText2" ng-keydown="handleEvt($event.keyCode+'키코드 눌러짐')"><p>{{message}} {{eventCnt}}</p>
</body>
이벤트 처리 템플릿
플러그인
지시자
a, form, input, ngApp, ngBind, ngChange, ngClass, ngClick, ngController, ngCloak, ngDbclick, ngDisabled, ngHide, ngHref,
ngInclude, ngModel, ngMousedown, ngRepeat, ngView, ...
BUILT-IN DIRECTIVE
<body><div class="container" ng-controller="demoCtrl">
<panel title="헬로" click="close()"><div>
<h2>환영합니다~</h2><p>PHPFest 2014!</p>
</div></panel><panel title="헬로2">
<p>XECon + PHPFest 2014!</p></panel>
</div></body>
app.html
<div class="panel panel-default"> <div class="panel-heading">
<h3 class="panel-title">{{title}}</h3> </div> <div class="panel-body" ng-transclude></div>
</div>
panel.tmpl.html
<script type="text/javascript">angular.module('demo', []).
directive('panel', ['$log', function($log){return {
scope: {title : "@",contents : "@",
}, restrict: 'AE',templateUrl: 'panel.tmpl.html',transclude: true,link: function($scope, iElm, iAttrs, controller) {
$(iElm).find('.panel-heading').click(function () {$(iElm).find('.panel-body').toggle();
})}
};}]);
}]);</script>
app.js
DOM 조작은 지시자 함수 안에서 만 사용.
컨트롤러에서 DOM 조작 하면 안됨.
AngularJS 란?
Google이 만든 웹 어플리케이션을 위한 Structural Framework
• 양방향 데이터 바인딩
• MVC 구조
• Template• Directive를 통한 컴포넌트 재사용
• E2E 테스팅 및 Mocks• 의존성 주입 (DI)• Router• ….
CRUD Apps 필수 기능 제공을 통한
(단일 페이지) 웹 어플리케이션 개발의 단순화
박수 박수
박수
QnA
감사합니다.