ProAngularJS Ch.6 스포츠 상점

※ 실행결과: http://study.jeju.onl/sportsstore/app.html

실제로 작동하는 웹앱을 제작한다.
스포츠 상점을 가정하고 제품정보 json 데이터로부터 카테고리와 상품 리스트를 가져와 선택한 카테고리별로 상품을 나열하고 페이지 내 최대 아이템 출력 갯수를 정해 페이지 번호로 선택해 볼 수 있다.

다음은 결과 캡쳐ProAngularJS-ch06-sportsStore

위 결과를 얻기 위해서 모두 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">
  
  

{{ item.name }} {{ item.price | currency }}

{{ item.description }}
</div> </div> </body> </html>

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 : "";
  }
});

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중

%d 블로거가 이것을 좋아합니다: