品优购项目记录:day03

今日目标:

        (1)理解和运用 angular js 的 service

        (2)理解好运用控制器继承

        (3)掌握代码生成器的使用

        (4)实现规格管理

        (5)实现模板管理



1、前段分层开发

1.1 JS 代码改造

// 自定义模块,引入分页模块
var app = angular.module('pinyougou', ['pagination']);

//自定义服务
app.service('brandService', function ($http) {

    // 分页查询品牌列表
    this.findByPage = function (page, size) {
        return $http.get('../brand/findByPage.do?page=' + page + '&size=' + size);
    };

    // 新增品牌
    this.add = function (entity) {
        return $http.post('../brand/add.do', entity);
    };

    // 按id查询品牌
    this.findOne = function (id) {
        return $http.get('../brand/findOne.do?id=' + id);
    };

    // 修改品牌
    this.update = function (entity) {
        return $http.post('../brand/update.do', entity);
    };

    // 删除品牌
    this.dele = function (ids) {
        return $http.get('../brand/delete.do?ids=' + ids);
    }

    this.search = function (page,size,queryParam) {
        return $http.post('../brand/search.do?page=' + page + '&size=' + size, queryParam);
    }


});


//自定义控制器
app.controller('brandController', function ($scope, brandService) {

    //分页控件配置
    $scope.paginationConf = {
        //当前页
        currentPage: 1,
        //总记录数
        totalItems: 10,
        //每页记录数
        itemsPerPage: 10,
        //可以选择的每页记录数
        perPageOptions: [10, 20, 30, 40, 50],
        //选择每页记录数事件
        onChange: function () {
            $scope.reloadList();
        }
    };
    //重新加载
    $scope.reloadList = function () {
        $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
    };

    /*
        分页查询品牌列表
     */
    $scope.findByPage = function (page, size) {
        brandService.findByPage(page, size).success(
            function (rtn) {
                //显示当前页的数据
                $scope.list = rtn.rows;
                //修改总记录数
                $scope.paginationConf.totalItems = rtn.total;
            }
        );
    };

    /*
        新增品牌、修改品牌
     */
    $scope.save = function () {
        var object = null;
        if ($scope.entity.id != null) {
            object = brandService.update($scope.entity);
        } else {
            object = brandService.add($scope.entity);
        }
        object.success(
            function (rtn) {
                alert(rtn.message);
                if (rtn.success) {
                    //重新加载数据
                    $scope.reloadList();
                }
            }
        );
    };

    /*
        加载要修改的品牌到编辑品牌表单
     */
    $scope.findOne = function (id) {
        brandService.findOne(id).success(
            function (rtn) {
                $scope.entity = rtn;
            }
        );
    };

    //记录被勾选的id值
    $scope.selectIds = [];

    /*
        更新被勾选的id值
     */
    $scope.updateSelection = function ($event, id) {
        if ($event.target.checked) {//选中状态
            //将id值加入selectIds
            $scope.selectIds.push(id);
        } else {//取消选中
            //获取id值的下标
            var index = $scope.selectIds.indexOf(id);
            //移除id
            $scope.selectIds.splice(index, 1);
        }
    };

    /*
        删除操作
     */
    $scope.dele = function () {
        brandService.dele($scope.selectIds).success(
            function (rtn) {
                alert(rtn.message);
                if (rtn.success) {
                    //重新加载数据
                    $scope.reloadList();
                }
            }
        );
    };

    /*
        条件查询
     */
    //初始化queryParam
    $scope.queryParam = {};
    $scope.search = function (page, size) {
        brandService.search(page, size, $scope.queryParam).success(
            function (rtn) {
                //显示当前页的数据
                $scope.list = rtn.rows;
                //修改总记录数
                $scope.paginationConf.totalItems = rtn.total;
            }
        );
    };


});



1.2 将改造后的 JS 分层,即将放入不同的 JS 文件中

(1)base_pagination.js
// 自定义模块,引入分页模块
var app = angular.module('pinyougou', ['pagination']);
(2)brandService.js
//自定义服务
app.service('brandService', function ($http) {

    // 分页查询品牌列表
    this.findByPage = function (page, size) {
        return $http.get('../brand/findByPage.do?page=' + page + '&size=' + size);
    };

    // 新增品牌
    this.add = function (entity) {
        return $http.post('../brand/add.do', entity);
    };

    // 按id查询品牌
    this.findOne = function (id) {
        return $http.get('../brand/findOne.do?id=' + id);
    };

    // 修改品牌
    this.update = function (entity) {
        return $http.post('../brand/update.do', entity);
    };

    // 删除品牌
    this.dele = function (ids) {
        return $http.get('../brand/delete.do?ids=' + ids);
    }

    this.search = function (page,size,queryParam) {
        return $http.post('../brand/search.do?page=' + page + '&size=' + size, queryParam);
    }

});

(3)brandController.js
//自定义控制器
app.controller('brandController', function ($scope, brandService) {

    //分页控件配置
    $scope.paginationConf = {
        //当前页
        currentPage: 1,
        //总记录数
        totalItems: 10,
        //每页记录数
        itemsPerPage: 10,
        //可以选择的每页记录数
        perPageOptions: [10, 20, 30, 40, 50],
        //选择每页记录数事件
        onChange: function () {
            $scope.reloadList();
        }
    };
    //重新加载
    $scope.reloadList = function () {
        $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
    };

    /*
        分页查询品牌列表
     */
    $scope.findByPage = function (page, size) {
        brandService.findByPage(page, size).success(
            function (rtn) {
                //显示当前页的数据
                $scope.list = rtn.rows;
                //修改总记录数
                $scope.paginationConf.totalItems = rtn.total;
            }
        );
    };

    /*
        新增品牌、修改品牌
     */
    $scope.save = function () {
        var object = null;
        if ($scope.entity.id != null) {
            object = brandService.update($scope.entity);
        } else {
            object = brandService.add($scope.entity);
        }
        object.success(
            function (rtn) {
                alert(rtn.message);
                if (rtn.success) {
                    //重新加载数据
                    $scope.reloadList();
                }
            }
        );
    };

    /*
        加载要修改的品牌到编辑品牌表单
     */
    $scope.findOne = function (id) {
        brandService.findOne(id).success(
            function (rtn) {
                $scope.entity = rtn;
            }
        );
    };

    //记录被勾选的id值
    $scope.selectIds = [];

    /*
        更新被勾选的id值
     */
    $scope.updateSelection = function ($event, id) {
        if ($event.target.checked) {//选中状态
            //将id值加入selectIds
            $scope.selectIds.push(id);
        } else {//取消选中
            //获取id值的下标
            var index = $scope.selectIds.indexOf(id);
            //移除id
            $scope.selectIds.splice(index, 1);
        }
    };

    /*
        删除操作
     */
    $scope.dele = function () {
        brandService.dele($scope.selectIds).success(
            function (rtn) {
                alert(rtn.message);
                if (rtn.success) {
                    //重新加载数据
                    $scope.reloadList();
                }
            }
        );
    };

    /*
        条件查询
     */
    //初始化queryParam
    $scope.queryParam = {};
    $scope.search = function (page, size) {
        brandService.search(page, size, $scope.queryParam).success(
            function (rtn) {
                //显示当前页的数据
                $scope.list = rtn.rows;
                //修改总记录数
                $scope.paginationConf.totalItems = rtn.total;
            }
        );
    };


});

(4)在品牌管理页面中引入这些 JS




1.3 控制器继承

(1)抽取出控制器中公共代码到baseController.js中
app.controller('baseController',function ($scope) {
    //分页控件配置
    $scope.paginationConf = {
        //当前页
        currentPage: 1,
        //总记录数
        totalItems: 10,
        //每页记录数
        itemsPerPage: 10,
        //可以选择的每页记录数
        perPageOptions: [10, 20, 30, 40, 50],
        //选择每页记录数事件
        onChange: function () {
            $scope.reloadList();
        }
    };
//重新加载
    $scope.reloadList = function () {
        $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
    };

//记录被勾选的id值
    $scope.selectIds = [];

    /*
        更新被勾选的id值
     */
    $scope.updateSelection = function ($event, id) {
        if ($event.target.checked) {//选中状态
            //将id值加入selectIds
            $scope.selectIds.push(id);
        } else {//取消选中
            //获取id值的下标
            var index = $scope.selectIds.indexOf(id);
            //移除id
            $scope.selectIds.splice(index, 1);
        }
    };
});


(2)使用 brandController 继承 baseController
    // 继承baseController
    $controller('baseController', {$scope: $scope});
注意:要使用继承,必须先将$controller 服务注入到brandController,并且要在引入brandController.js之前引入baseController.js


2、规格管理


2.1 规格列表显示,后端代码与JS代码使用生成器生成,只需修改页面

(1)引入 JS 文件


(2)引入 angular JS


(3)循环获取值


2.2 新增规格



需求1:点击新增规格选项,在表格中新增一行
(1)点击新建按钮时,初始化绑定的变量



(2)编写 JS 代码(specificationController.js)
    //新增规格选项
    $scope.addTableRow = function () {
		$scope.entity.specificationOptionList.push({});
    }

(3)为新增规格选项按钮绑定事件


需求2:点击删除按钮,删除当前表格行

(1)编写 JS 代码(specificationController.js)

    //删除规格选项
	$scope.deleTableRow = function (index) {
		$scope.entity.specificationOptionList.splice(index,1);
    }

(2)为删除按钮绑定事件,index参数可以使用 $index 直接获取



需求3:点击保存按钮,提交到后端进行保存
(1)后端代码

    a、pinyougou-dao,修改TbSpecificationMapper.xml中的insert映射,加入代码,为了在插入规格后获取其ID,用于后续操作

    <selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
      SELECT LAST_INSERT_ID() AS id
    </selectKey>
    b、创建一个实体类,用于接受前端传过来的参数
package com.pinyougou.pojogroup;

import com.pinyougou.pojo.TbSpecification;
import com.pinyougou.pojo.TbSpecificationOption;

import java.util.List;

/**
 * 规格和规格选项组合实体类
 * Author xushuai
 * Description
 */
public class Specification {

    /** 品牌规格 */
    private TbSpecification specification;
    /** 规格选项 */
    private List<TbSpecificationOption> specificationOptionList;

    public TbSpecification getSpecification() {
        return specification;
    }

    public void setSpecification(TbSpecification specification) {
        this.specification = specification;
    }

    public List<TbSpecificationOption> getSpecificationOptionList() {
        return specificationOptionList;
    }

    public void setSpecificationOptionList(List<TbSpecificationOption> specificationOptionList) {
        this.specificationOptionList = specificationOptionList;
    }
}

     c、服务层接口(sellergoods-interface),重载add方法

    /**
     * 新增
     *
     * @param specification 规格组合实体
     */
    void add(Specification specification);

     d、服务层实现(sellergoods-service),新增实现

    @Override
    public void add(Specification specification) {
        //从组合实体中获取规格对象
        TbSpecification tbSpecification = specification.getSpecification();
        //执行保存
        specificationMapper.insert(tbSpecification);

        //从组合试题中获取规格选项
        List<TbSpecificationOption> tbSpecificationOptionList = specification.getSpecificationOptionList();
        //循环保存
        for (TbSpecificationOption option : tbSpecificationOptionList) {
            //设置规格id
            option.setSpecId(tbSpecification.getId());
            //保存规格选项
            specificationOptionMapper.insert(option);
        }
    }

     d、控制层(manager-web)

	/**
	 * 增加
	 * @param specification
	 * @return
	 */
	@RequestMapping("/add")
	public Result add(@RequestBody Specification specification){
		try {
			specificationService.add(specification);
			return new Result(true, "增加成功");
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "增加失败");
		}
	}


(2)后端代码

        a、为规格名称绑定变量



        b、为保存按钮添加事件


	//保存 
	$scope.save=function(){				
		var serviceObject;//服务层对象  				
		if($scope.entity.specification.id!=null){//如果有ID
			serviceObject=specificationService.update( $scope.entity ); //修改  
		}else{
			serviceObject=specificationService.add( $scope.entity  );//增加 
		}				
		serviceObject.success(
			function(response){
				if(response.success){
					//重新查询 
		        	$scope.reloadList();//重新加载
				}else{
					alert(response.message);
				}
			}		
		);				
	}



2.3 修改规格

(1)后端代码

    a、服务层接口(sellergoods-interface)

    /**
     * 根据ID获取实体
     *
     * @param id
     * @return
     */
    Specification findOne(Long id);

        b、服务层实现(sellergoods-service)

    /**
     * 根据ID获取实体
     *
     * @param id
     * @return
     */
    @Override
    public Specification findOne(Long id) {
        //查询规格
        TbSpecification tbSpecification = specificationMapper.selectByPrimaryKey(id);
        //封装规格选项查询条件
        TbSpecificationOptionExample specificationOptionExample = new TbSpecificationOptionExample();
        specificationOptionExample.createCriteria().andSpecIdEqualTo(id);
        //查询规格选项
        List<TbSpecificationOption> tbSpecificationOptions = specificationOptionMapper.selectByExample(specificationOptionExample);

        //创建规格组合实体类
        Specification specification = new Specification();
        specification.setSpecification(tbSpecification);
        specification.setSpecificationOptionList(tbSpecificationOptions);

        return specification;
    }

        c、控制层

	/**
	 * 获取实体
	 * @param id
	 * @return
	 */
	@RequestMapping("/findOne")
	public Specification findOne(Long id){
		return specificationService.findOne(id);		
	}

(2)前端无需修改




2.4 删除规格

(1)后端代码,只需要修改服务层实现中的delete方法
    /**
     * 批量删除
     */
    @Override
    public void delete(Long[] ids) {
        for (Long id : ids) {
            //删除规格数据
            specificationMapper.deleteByPrimaryKey(id);

            //删除规格选项数据
            TbSpecificationOptionExample specificationOptionExample = new TbSpecificationOptionExample();
            specificationOptionExample.createCriteria().andSpecIdEqualTo(id);
            //删除规格选项
            specificationOptionMapper.deleteByExample(specificationOptionExample);
        }
    }

(2)前端

        a、为复选框加入单击事件


        b、为删除按钮绑定事件







3、模板管理



3.1 模板列表和规格列表几乎一样,参考规格列表


3.2 品牌下拉列表(select2组件)

(1)引入select2的js和css文件
    <link rel="stylesheet" href="../plugins/select2/select2.css" />
    <link rel="stylesheet" href="../plugins/select2/select2-bootstrap.css" />
    <script src="../plugins/select2/select2.min.js" type="text/javascript"></script>
    <script type="text/javascript" src="../js/angular-select2.js">  </script>

注意:angular-select2.js 必须放在自定义模块的js文件后面引入,因为angular-select2中会使用到app

(2)在controller中新增变量,即下拉菜单中的数据



(3)在页面中添加select2组件



(4)效果




3.3 品牌下拉列表从后端获取数据集

(1)新增mapper映射(TbBrandMapper.xml)
  <!-- 查询品牌列表,并封装为Map返回 -->
  <select id="selectOptionList" resultType="java.util.Map">
    select id,name as text
    from tb_brand
  </select>

(2)BrandMapper接口,新增对应方法
    List<Map> selectOptionList();

(3)服务层接口(BrandService)
    /**
     * 返回品牌下拉列表数据
     *
     * @return java.util.List<java.util.Map>
     */
    List<Map> selectOptionList();

(4)服务层实现(BrandServiceImpl)
	@Override
	public List<Map> selectOptionList() {
		return brandMapper.selectOptionList();
	}

(5)控制层(BrandController)
    /**
     * 获取品牌下拉列表需要的品牌列表数据格式
     *
     * @return java.util.List<java.util.Map>
     */
    @RequestMapping("/selectOptionList")
    public List<Map> selectOptionList() {
        return brandService.selectOptionList();
    }

(6)在前端 brandService.js 中,添加方法
    // 获取品牌下拉列表需要的数据集
    this.selectOptionList = function () {
        return $http.get('../brand/selectOptionList.do');
    }

(7)在 typeTemplateController.js 中注入 brandService 服务

注意:需要在页面引入 brandService.js 文件


(8)在 typeTemplateController.js 中定义加载品牌列表数据的方法
	//获取品牌列表下拉列表需要的数据集
	$scope.findBrandList = function () {
		brandService.selectOptionList().success(
		    function (rtn) {
                        $scope.brandList = {data:rtn};
                    }    
		);
        }


(9)在 angular js 初始化调用指令,调用该方法



(10)测试




3.4 规格下拉列表和品牌下拉列表做法一致,参考品牌下拉列表




3.5 增加和删除扩展属性表格行



(1)在点击新建按钮时,初始化扩展属性的数组


(2)编写新增行方法
    //新增扩展属性行
    $scope.addTableRow = function () {
		$scope.entity.customAttributeItems.push({});
    }


(3)为新增扩展属性按钮绑定单击事件



(4)绑定扩展属性数组到表格行



(5)编写删除行方法
    //删除扩展属性行
	$scope.deleTableRow = function (index) {
		$scope.entity.customAttributeItems.splice(index,1);
	}

(6)为删除按钮绑定单击事件


3.6 点击保存,保存模板信息

(1)为商品类型绑定变量


(2)为保存按钮绑定单击事件




3.7 修改模板信息

(1)为修改按钮绑定单击事件



(2)修改 findOne 方法

效果:




3.8 删除模板,只需要为复选框绑定单击事件,并给删除按钮绑定单击事件




3.9 优化模板列表显示


我们需要将信息以更友好的方式展现出来,如下图形式


(1)提交一个转换方法到baseController.js中
    /*
        json数据转换方法
     */
    $scope.jsonToString = function (jsonString, key) {
        //将jsonString转换为json对象
        var json = JSON.parse(jsonString);

        //存放转换后的值
        var value = '';

        //遍历json进行转换
        for(var i = 0; i < json.length; i++) {
            if(i>0) {
                value += ',';
            }
            value += json[i][key];
        }

        return value;
    }

(2)在页面调用这个方法


(3)效果







猜你喜欢

转载自blog.csdn.net/qq1031893936/article/details/80950424