《Pro AngularJS》学习小结-01

《Pro AngularJS》该书以一个SportsStore案例为主线铺开。

一、开发环境设置

该书中所用的数据库data server开发环境是Deployed,从来没听说过,而且作者也说该数据库data server没什么人用,我干脆弃用之。其他的环境包括

  • NodeJS——这个必须装
  • karma——测试环境,前期还没有用到,以后认真研究,毕竟AngularJS一大特点是Unit Test
  • bootstrap——这个现在应该普遍使用了,O(∩_∩)O
  • webstorm——现在唯一支持AngularJS插件的IDE

我基本没学过NodeJS,只好使用了webstorm中的内置项目:Node.js Boilerplate来傻瓜化新建项目了。其启动NodeJS过程如下图(基本可按指示一步一步做⊙﹏⊙):

新建好项目后将所有文件放在static目录下,就先这样凑合着用了。我也暂时不使用数据库,直接使用JSON文件。

我的项目目录如下:

说明:

  • 首页文件名必须是index.html,其他的html文件我放在partial目录下(这个可以自己定义)
  • 在server.js中可以修改NodeJs的port,默认的是8081,在浏览器中输入http://localhost:8081可直接跳转到static目录下的index.html

二、准备数据

我不熟悉NodeJS,使用一个Json文件作为数据源

[

    { "name" : "Product #1", "description" : "A product", "category": "Category #1", "price": "100" },

    { "name" : "Product #2", "description" : "A product", "category": "Category #1", "price": "110" },

    { "name" : "Product #3", "description" : "A product", "category": "Category #2", "price": "210" },

    { "name" : "Product #4", "description" : "A product", "category": "Category #3", "price": "202" },

    { "name" : "Product #1", "description" : "A product", "category": "Category #1", "price": "100" },

    { "name" : "Product #2", "description" : "A product", "category": "Category #1", "price": "110" },

    { "name" : "Product #3", "description" : "A product", "category": "Category #2", "price": "210" },

    { "name" : "Product #4", "description" : "A product", "category": "Category #3", "price": "202" }

]
products.json

创建sportsStore.js来引入并定义数据

angular.module("sportsStore")

    .controller("sportsStoreCtrl", function ($scope, $http) {

        $scope.data = {};

        $http.get("products.json")

            .success(function(data){

                $scope.data.products = data;

            }).error(function(error){

                $scope.data.error = error;

            });

});

三、显示产品细节页面——直接上代码,即index.html

该代码主要用来显示产品的详细信息,即右边的面板panel的内容

<!DOCTYPE html>

<html ng-app="sportsStore">   <!-- 标志AngularJs的开始 -->

<head>

<title>SportsStore</title>

<script src="js/lib/angular.js"></script>

<link href="css/bootstrap.css" rel="stylesheet" />

<link href="css/bootstrap-theme.css" rel="stylesheet" />

<script> angular.module("sportsStore", []); <!--加入sportsStore这个AngularJS应用 --> </script>

<script src="js/controllers/sportsStore.js"></script>

</head>

<body ng-controller="sportsStoreCtrl">   <!-- 控制器sportStoreCtrl将应用于整个页面 -->

    <div class="navbar navbar-inverse">

        <a class="navbar-brand" href="#">SPORTS STORE</a>

     </div>

    <div class="panel panel-default row">

        <div class="col-xs-3 col-md-3">Categories go here</div>

        <div class="col-xs-8 col-md-8">

        <div class="well" ng-repeat="item in data.products">

          <h3>

          <strong>{{item.name}}</strong>           <!--数据绑定 -->

          <span class="pull-right label label-primary">

          {{item.price | currency}} <!-- currency filter将使该span的内容显示为货币格式 -->

          </span>

          </h3>

          <span class="lead">{{item.description}}</span>     <!--数据绑定 -->

        </div>

        </div>

    </div>

</body>

</html>

四、定义左侧Category导航面板

1、加入的HTML

...
angular.module("sportsStore", ["customFilters"]); <!--加入customFilters模块 -->
...
<
div class="panel panel-default row"> <div class="col-xs-3 col-md-3">   <a ng-click="selectCategory()" class="btn btn-block btn-default btn-lg">Home</a> <!--加入click事件 -->    <a ng-repeat="item in data.products | orderBy:'category' | unique:'category'" <!--添加unique过滤,定义为按category属性过滤 -->         ng-click="selectCategory(item)" class=" btn btn-block btn-default btn-lg"> <!--加入click事件 -->     {{item}}    </a> </div> ...... </div>

2. 新建customFilters.js——创建一个unique过滤,用来过滤Category

angular.module("customFilters", [])

    .filter("unique", function () {

        return function (data, propertyName) {

            if (angular.isArray(data) && angular.isString(propertyName)) {

                var results = [];

                var keys = {};

                for (var i = 0; i < data.length; i++) {

                    var val = data[i][propertyName];

                    if (angular.isUndefined(keys[val])) { //?

                        keys[val] = true;

                        results.push(val);

                    }

                }

                return results;

            } else {

                return data;

            }

        }

});

3. 新建productListControllers.js —— 实现按分类category显示产品信息(动态显示右边的面板内容)

angular.module("sportsStore")

.controller("productListCtrl", function ($scope, $filter) {

  var selectedCategory = null;

  $scope.selectCategory = function (newCategory) {

    selectedCategory = newCategory;

  }

  $scope.categoryFilterFn = function (product) {

    return selectedCategory == null ||

    product.category == selectedCategory;

  }

});

注意:

  • selectedCategory只是一般普通的Javascript变量,没有定义在$scope范围内,也就是说不能从directive或视图view中绑定的数据访问该变量
  • categoryFilterFn是用来在产品详细信息面板中过滤product objects

4. 应用productListControllers和过滤产品——修改index.html

<divclass="panel panel-default row" ng-controller="productListCtrl">   <!--加入新的div层,使左右面板包含到该div,并加入productListCtrl -->

  <div class="col-xs-3 col-md-3">

    <a ng-click="selectCategory()" class="btn btn-block btn-default btn-lg">Home</a>

    <a ng-repeat="item in data.products | orderBy:'category' | unique:'category'"

      ng-click="selectCategory(item)" class=" btn btn-block btn-default btn-lg">

      {{item}}

    </a>

  </div>

  <div class="col-xs-8 col-md-8">

    <div class="well" ng-repeat="item in data.products | filter:categoryFilterFn"> 
<!--加入categoryFilterFn,使得该div的内容随着右边面板的点击事件而变化-->
    <h3>       <strong>{{item.name}}</strong>       <span class="pull-right label label-primary">         {{item.price | currency}}       </span>     </h3>     <span class="lead">{{item.description}}</span>     </div>   </div> </div>

5. 高亮显示左边导航按钮(Highlighting the Selected Category)——使用

修改productListControllers.js

angular.module("sportsStore")

.constant("productListActiveClass", "btn-primary") //使用constant方法定义一个常量productListActiveClass

.controller("productListCtrl", function ($scope, $filter, productListActiveClass) {//

  var selectedCategory = null;

  $scope.selectCategory = function (newCategory) {

    selectedCategory = newCategory;

  }

  $scope.categoryFilterFn = function (product) {

    return selectedCategory == null ||

    product.category == selectedCategory;

  }

  $scope.getCategoryClass = function(category) {     return selectedCategory == category ? productListActiveClass : "";   }

});

修改index.html中左边面板相关内容

...

.controller("productListCtrl", function ($scope, $filter, productListActiveClass) {

...

<div class="col-xs-3 col-md-3">

  <a ng-click="selectCategory()" class="btn btn-block btn-default btn-lg">Home</a>

  <a ng-repeat="item in data.products | orderBy:'category' | unique:'category'"

    ng-click="selectCategory(item)" class=" btn btn-block btn-default btn-lg"

    ng-class="getCategoryClass(item)">

    {{item}}

  </a>

</div>

...

四、加入分页(pagination)

1. 修改productListControllers.js

angular.module("sportsStore")

.constant("productListActiveClass", "btn-primary")

.constant("productListPageCount", 3) //常量productlistPageCount,每页显示的产品数目

.controller("productListCtrl", function ($scope, $filter, productListActiveClass, productListPageCount) {

  var selectedCategory = null;

  $scope.selectedPage = 1;

  $scope.pageSize =

你可能感兴趣的:(AngularJS)