※ 실행결과: http://study.jeju.onl/sportsstore/app.html
실제로 작동하는 웹앱을 제작한다.
스포츠 상점을 가정하고 제품정보 json 데이터로부터 카테고리와 상품 리스트를 가져와 선택한 카테고리별로 상품을 나열하고 페이지 내 최대 아이템 출력 갯수를 정해 페이지 번호로 선택해 볼 수 있다.
위 결과를 얻기 위해서 모두 4개의 파일이 사용되었다.
해당 코드에 주석을 첨부하였으니 참고할 것!
* 책대로 작성한 경우 반드시 작동된다. 안된다면 십중팔구 mis-spelling 탓이다.
1. 메인 페이지 /app.html
<!DOCTYPE html> <html ng-app="sportsStore"> <head> <title>Sports Store</title> <link href="/node_modules/bootstrap/dist/css/bootstrap.css" rel="stylesheet" /> <link href="/node_modules/bootstrap/dist/css/bootstrap-theme.css" rel="stylesheet" /> /node_modules/angular/angular.js // 최상위 컨트롤러 선언 angular.module("sportsStore", ["customFilters"]); http://controllers/sportsStore.js http://filters/customFilters.js http://controllers/productListCtrl.js </head> <body ng-controller="sportsStoreCtrl"></div> </div> </body> </html>{{ item.name }} {{ item.price | currency }}
{{ item.description }}2. 최상위 콘트롤러 /controllers/sportsStore.js
angular.module("sportsStore") .controller("sportsStoreCtrl", function($scope) { $scope.Math=Math; $scope.data = { products: [ { name: "Product #1", description: "A product", category: "Category #1", price: 100 }, { name: "Product #2", description: "B product", category: "Category #1", price: 110 }, { name: "Product #3", description: "C product", category: "Category #2", price: 210 }, { name: "Product #4", description: "D product", category: "Category #3", price: 202 } ] }; });3. 필터 /filters/customFilters.js
angular.module("customFilters", []) .filter("unique", function() { return function(data, propertyName) { // data is array and propertyName is string if (angular.isArray(data) && angular.isString(propertyName)) { var results = []; var keys = {}; // for all data for (var i=0; i<data.length; i++) { var val = data[i][propertyName]; // if val is new, then .. if (angular.isUndefined(keys[val])) { keys[val] = true; // check true results.push(val); // store to results } } return results; } else { return data; } }; }) .filter("range", function($filter) { return function(data, page, size) { if (angular.isArray(data) && angular.isNumber(page) && angular.isNumber(size)) { var start_index = (page - 1) * size; if (data.length < start_index) { return []; } else { return $filter("limitTo")(data.splice(start_index), size); } } else { return data; } } }) .filter("pageCount", function() { return function(data, size) { if (angular.isArray(data)) { var result = []; //var pLimit = Math.ceil(data.length/size); //console.log("Math.ceil(data.length/size) = "+pLimit+" ("+data.length+"/"+size+")"); for (var i=0; i<Math.ceil(data.length/size); i++) { result.push(i); } return result; } else { return data; } } }) ;4. 하위 콘트롤러 /controllers/productListCtrl.js
angular.module("sportsStore") .constant("productListActiveClass", "btn-primary") .constant("productListPageCount", 3) .controller("productListCtrl", function($scope, $filter , productListActiveClass, productListPageCount) { var selectedCategory = null; $scope.selectedPage = 1; $scope.pageSize = productListPageCount; // newCategory 인자가 없으면 null(전체), 있으면 카테고리 지정 $scope.selectCategory = function(newCategory) { selectedCategory = newCategory; $scope.selectedPage = 1; }; $scope.selectPage = function(newPage) { $scope.selectedPage = newPage; } // 카테고리 지정이 없거나 또는 해당 카테고리일 경우에만 true $scope.categoryFilterFn = function(product) { return selectedCategory == null || product.category == selectedCategory; }; // 선택 카테고리와 같으면 강조표시 style 클래스를 반환 (constant로 선언) $scope.getCategoryClass = function(category) { // Note: .constant 지시자가 먹히려면 controller 함수 인자로 받아야 한다!! //console.log("productListActiveClass = " + productListActiveClass); return (selectedCategory == category) ? productListActiveClass : ""; }; $scope.getPageClass = function(page) { return ($scope.selectedPage == page) ? productListActiveClass : ""; } });