品优购电商系统 3 - 规格及模板管理

本文部分内容来自黑马49期项目实战-品优购电商系统开发

课程目标

  1. 理解和运用AngularJS的service
  2. 理解和运用控制器继承
  3. 掌握代码生成器的使用
  4. 实现规格管理
  5. 实现模板管理

前端分层开发

需求分析

  1. 为了方便维护,使用MVC的设计模式,将代码进行分层,提高程序的可维护性。

代码分离

前端基础层
  1. 在pinyougou-manager-web工程js下创建base.js和base_pagination.js

    1. base.js 用于不需要分页功能的页面

      // 定义模块;
      var app = angular.module("pinyougou", []);
      
    2. base_pagination.js用于需要分页功能的页面

      // 定义模块;
      var app = angular.module("pinyougou", ["pagination"]);
      
前端服务层
  1. 在pinyougou-manager-web工程js文件夹下创建service文件夹,创建brandService.js

    // 品牌服务层
    app.service('brandService', function ($http) {
    
        this.findById = function (id) {
            return $http.get("../brand/findOne.do?id="+id);
        }
    
        // 查询品牌列表
        this.findPage = function (page, rows) {
            return $http.get("../brand/findPage.do?page="+page+"&pageSize="+rows);
        };
    
        // 新增产品
        this.save = function (entity) {
            return $http.post("../brand/add.do", entity);
        };
    
        // 更新产品
        this.update = function (entity) {
            return $http.post("../brand/update.do", entity);
        };
    
        // 批量删除
        this.deleteBrands = function (ids) {
            return $http.get("../brand/delete.do?ids=" + ids);
        };
    
        // 条件查询
        this.searchBrand = function (page, rows, searchEntity) {
            return $http.post("../brand/search.do?page=" + page + "&pageSize=" + rows, searchEntity);
        };
    
    });
    
前端控制层
  1. 在pinyougou-manager-web工程js文件夹下创建controller文件夹,创建brandController.js

    // 定义控制器
    app.controller('brandController', function ($scope, $controller, brandService) {
    
        // 查询品牌列表
        $scope.findPage = function (page, rows) {
            brandService.findPage(page, rows).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        };
    
        // 重新加载数据列表
        $scope.reloadBrandList = function() {
    
            // 切换页码
            $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
        };
    
    
        // 分页
        $scope.paginationConf = {
            // 当前页码
            currentPage: 1,
            // 总条数
            totalItems: 10,
            // 每页数量
            itemsPerPage: 10,
            // 页码选项
            perPageOptions: [10, 20, 30, 40, 50],
            // 更改页面时触发事件
            onChange: function () {
                // 重新加载
                $scope.reloadBrandList();
            }
        };
    
        // 新增产品
        $scope.save = function () {
            // 区分是保存还是修改
            var object;
    
            // 如果有实体id,则调用更新方法
            if ($scope.entity.id != null) {
                // 更新
                object = brandService.update($scope.entity);
            } else {
                // 保存
                object = brandService.save($scope.entity);
            }
    
            object.success(
                function (response) {
                    if (response.success) {
                        // 保存成功
                        alert(response.message);
                        // 重新加载数据
                        $scope.reloadBrandList();
                    } else {
                        alert(response.message);
                    }
                }
            );
        };
    
    
        // 查询品牌实体
        $scope.findOne = function (id) {
            brandService.findById(id).success(
                function (response) {
                    $scope.entity = response;
                }
            );
        };
    
        // 选中的Id集合
        $scope.selectIds = [];
    
        // 更新复选
        $scope.updateSelection = function ($event, id) {
    
            // 如果选中,添加到数组中
            if ($event.target.checked) {
                $scope.selectIds.push(id);
            } else {
                // splice方法,从数组的指定位置移除指定个数的元素,第一个参数为位置,第二个参数是移除的个数
                var index = $scope.selectIds.indexOf(id);
                $scope.selectIds.splice(index, 1);
            }
        };
    
        // 批量删除
        $scope.deleteBrands = function () {
    
            brandService.deleteBrands($scope.selectIds).success(
                function (response) {
                    if (response.success == true) {
                        // 重新加载数据
                        $scope.reloadBrandList();
                        $scope.selectIds = [];
                    } else {
                        // 保存失败
                        alert(response.message);
                    }
                }
            );
        };
    
        // 定义搜索对象
        $scope.searchEntity = {};
    
        // 条件查询
        $scope.search = function (page, rows) {
    
            brandService.searchBrand(page, rows, $scope.searchEntity).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        }
    
    });
    
修改页面
  1. 去掉brand.html原来的JS代码,导入js文件

    <script type="text/javascript" src="../js/base_pagination.js"></script>
    <script type="text/javascript" src="../js/service/brandService.js"></script>
    <script type="text/javascript" src="../js/controller/brandController.js"></script>
    

控制器继承

需求分析

  1. 有些功能每个页面都有可能用到,比如分页,复选框等,为了重复编写,我们通过集成的方式来实现。

前端代码

建立父控制器
  1. 在pinyougou-manager-web工程js/controller下,创建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 = [];
    
        // 更新复选
        $scope.updateSelection = function ($event, id) {
    
            // 如果选中,添加到数组中
            if ($event.target.checked) {
                $scope.selectIds.push(id);
            } else {
                // splice方法,从数组的指定位置移除指定个数的元素,第一个参数为位置,第二个参数是移除的个数
                var index = $scope.selectIds.indexOf(id);
                $scope.selectIds.splice(index, 1);
            }
        };
    
    });
    
修改品牌控制器层
  1. 修改brandController.js

    // 定义控制器
    app.controller('brandController', function ($scope, $controller, brandService) {
    
        // AngularJS中的继承: 伪继承
        $controller('baseController', {$scope: $scope});
    
        // 查询品牌列表
        $scope.findPage = function (page, rows) {
            brandService.findPage(page, rows).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        };
    
        // 重新加载数据列表
        $scope.reloadBrandList = function() {
    
            // 切换页码
            $scope.search($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
        };
    
    
        // 新增产品
        $scope.save = function () {
            // 区分是保存还是修改
            var object;
    
            // 如果有实体id,则调用更新方法
            if ($scope.entity.id != null) {
                // 更新
                object = brandService.update($scope.entity);
            } else {
                // 保存
                object = brandService.save($scope.entity);
            }
    
            object.success(
                function (response) {
                    if (response.success) {
                        // 保存成功
                        alert(response.message);
                        // 重新加载数据
                        $scope.reloadBrandList();
                    } else {
                        alert(response.message);
                    }
                }
            );
        };
    
    
        // 查询品牌实体
        $scope.findOne = function (id) {
            brandService.findById(id).success(
                function (response) {
                    $scope.entity = response;
                }
            );
        };
    
    
        // 批量删除
        $scope.deleteBrands = function () {
    
            brandService.deleteBrands($scope.selectIds).success(
                function (response) {
                    if (response.success == true) {
                        // 重新加载数据
                        $scope.reloadBrandList();
                        $scope.selectIds = [];
                    } else {
                        // 保存失败
                        alert(response.message);
                    }
                }
            );
        };
    
        // 定义搜索对象
        $scope.searchEntity = {};
    
        // 条件查询
        $scope.search = function (page, rows) {
    
            brandService.searchBrand(page, rows, $scope.searchEntity).success(
                function (response) {
                    $scope.brandList = response.rows;
                    $scope.paginationConf.totalItems = response.total;
                }
            );
        }
    
    });
    
    1. $controller也是angular提供的服务,可以实现伪继承,实际上是与BaseController共享$scope
  2. 在brand.html中导入baseController.js

    <script type="text/javascript" src="../js/controller/baseController.js"></script>
    

测试

  1. 刷新品牌管理列表,数据正常显示

    这里写图片描述

  2. 点击修改,保存成功

    这里写图片描述

导入生成的代码

  1. 导入生成的代码

规格管理

需求及表结构分析

需求
  1. 实现规格管理功能

    这里写图片描述

表结构
  1. tb_specification 规格表

    字段类型长度含义
    IdBigint主键
    Spec_nameVarchar255规格名称
  2. tb_specification_option 规格选项表

    字段类型长度含义
    IdBigint主键
    Option_nameVarchar200规格选项名称
    Spec_idBigint30规格ID
    OrdersInt11排序

规格列表

引入JS
  1. 修改pinyougou-manager-web工程的specification.html

    <script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
    <script src="../plugins/angularjs/pagination.js"></script>
    <link rel="stylesheet" href="../plugins/angularjs/pagination.css">
    	
    <script type="text/javascript" src="../js/base_pagination.js"></script>
    <script type="text/javascript" src="../js/service/specificationService.js"></script>
    <script type="text/javascript" src="../js/controller/baseController.js"></script>
    <script type="text/javascript" src="../js/controller/specificationController.js"></script>
    
加载列表数据
  1. 在body元素指定模块名和控制器名

    <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="specificationController">
    
  2. 加载数据,添加分页

    <!--数据列表-->
    <table id="dataList" class="table table-bordered table-striped table-hover dataTable">
      <thead>
          <tr>
              <th class="" style="padding-right:0px">
                  <input id="selall" type="checkbox" class="icheckbox_square-blue">
              </th> 
    		  <th class="sorting_asc">规格ID</th>
    	      <th class="sorting">规格名称</th>									     												
              <th class="text-center">操作</th>
          </tr>
      </thead>
      <tbody>
          <tr ng-repeat="entity in list">
              <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
              <td>{{ entity.id }}</td>
    	      <td>{{ entity.specName }}</td>
              <td class="text-center">                                           
             	  <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal">修改</button>                                           
              </td>
          </tr>
      </tbody>
    </table>
    <!--数据列表/-->
    
    <!-- 分页 -->
    <tm-pagination conf="paginationConf"></tm-pagination>
    

新增规格

新增行的实现
  1. 修改specificationController.js新增以下代码

    // 增加规格选项行
    $scope.addTableRow=function(){
    	$scope.entity.specificationOptionList.push({});			
    }
    
  2. 修改specification.html的“新建选项”按钮和加载表格编辑框列表

    <!-- 规格选项 -->
    <div class="btn-group">
        <button type="button" class="btn btn-default" title="新建" ng-click="addTableRow()"><i class="fa fa-file-o"></i> 新增规格选项
        </button>
    
    </div>
    
    <table class="table table-bordered table-striped table-hover dataTable">
        <thead>
        <tr>
            <th class="sorting">规格选项</th>
            <th class="sorting">排序</th>
            <th class="sorting">操作</th>
        </thead>
        <tbody>
        <tr ng-repeat="pojo in entity.specificationOptionList">
            <td>
                <input ng-model="pojo.optionName" class="form-control" placeholder="规格选项">
            </td>
            <td>
                <input ng-model="pojo.orders" class="form-control" placeholder="排序">
            </td>
            <td>
                <button type="button" class="btn btn-default" title="删除"><i class="fa fa-trash-o"></i> 删除
                </button>
            </td>
        </tr>
        </tbody>
    </table>
    
  3. 修改“新建”按钮,弹出窗口时对entity进行初始化,否则添加规格选项会报错

    <button type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ng-click="entity={'specificationOptionList':[]}"><i class="fa fa-file-o"></i> 新建 </button>
    
删除行的实现
  1. 修改specificationController.js新增以下代码

    //删除规格选项行
    $scope.deleTableRow=function(index){
        $scope.entity.specificationOptionList.splice(index,1);
    }
    
  2. 修改每行的删除按钮,使用$index 用于获取ng-repeat指令循环中的索引

    <button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i class="fa fa-trash-o"></i> 删除 </button>
    
提交保存
  1. 思路: 将规格和规格选项数据合并成一个对象来传递,需要用一个对象将两个对象组合起来。在业务逻辑中,得到组合对象中的规格和规格选项列表,插入规格返回规格ID,然后循环插入规格选项。

  2. 增加规格选项,必须知道新增规格的ID,需要修改pinyougou-dao的TbSpecificationMapper.xml,在insert节点后添加

    <insert id="insert" parameterType="com.huangwangxin.pojo.TbSpecification" >
      	<selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
    		SELECT LAST_INSERT_ID() AS id
    	</selectKey>
        insert into tb_specification (id, spec_name)
        values (#{id,jdbcType=BIGINT}, #{specName,jdbcType=VARCHAR})
    </insert>
    
  3. 在pinyougou-pojo新增group包,创建Specificatio类

    package com.huangwangxin.group;
    
    import com.huangwangxin.pojo.TbSpecification;
    import com.huangwangxin.pojo.TbSpecificationOption;
    
    import java.io.Serializable;
    import java.util.List;
    
    
    /**
     * 规格组合实体类
     * @author Administrator
     *
     */
    public class Specification implements Serializable{
    
    	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;
    	}
    
    }
    
  4. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 增加
     */
    public void add(Specification specification);
    
  5. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 增加
     */
    @Override
    public void add(Specification specification) {
    	//获取规格实体
    	TbSpecification tbspecification = specification.getSpecification();				
    	specificationMapper.insert(tbspecification);	
    	
    	//获取规格选项集合
    	List<TbSpecificationOption> specificationOptionList = specification.getSpecificationOptionList();
    	for( TbSpecificationOption option:specificationOptionList){
    		option.setSpecId(tbspecification.getId());//设置规格ID
    		specificationOptionMapper.insert(option);//新增规格
    	}
    }
    
  6. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 增加
     *
     * @param specification the specification
     * @return result
     */
    @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, "增加失败");
    }
    
  7. 修改页面specification.html

    1. 绑定规格名称

      <table class="table table-bordered table-striped" width="800px">
          <tr>
              <td>规格名称</td>
              <td><input class="form-control" placeholder="规格名称" ng-model="entity.specification.specName"></td>
          </tr>
      </table>
      
    2. 绑定保存按钮事件

      <button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>
      

修改规格

获取规格数据
  1. 实现思路:通过规格ID,到后端查询规格和规格选项列表,然后通过组合实体类返回结果

  2. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 根据ID获取实体
     * @param id
     * @return
     */
    public Specification findOne(Long id);
    
  3. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 根据ID获取实体
     * @param id
     * @return
     */
    @Override
    public Specification findOne(Long id){
    	
    	Specification specification=new Specification();
    	//获取规格实体
    	TbSpecification tbSpecification = specificationMapper.selectByPrimaryKey(id);
    	specification.setSpecification(tbSpecification);
    	
    	//获取规格选项列表	
    	TbSpecificationOptionExample example=new TbSpecificationOptionExample();
    	TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
    	criteria.andSpecIdEqualTo(id);
    	List<TbSpecificationOption> specificationOptionList = specificationOptionMapper.selectByExample(example);
    	
    	specification.setSpecificationOptionList(specificationOptionList);
    	
    	return specification;//组合实体类
    }
    
  4. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 获取实体
     * @param id
     * @return
     */
    @RequestMapping("/findOne")
    public Specification findOne(Long id){
    	return specificationService.findOne(id);
    }
    
  5. 修改页面specification.html的修改按钮

    <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改</button>
    
保存修改结果
  1. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 修改
     */
    public void update(Specification specification);
    
  2. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 修改
     */
    @Override
    public void update(Specification specification){
    	
    	//获取规格实体
    	TbSpecification tbspecification = specification.getSpecification();				
    	specificationMapper.updateByPrimaryKey(tbspecification);	
    	
    	//删除原来规格对应的规格选项
    	TbSpecificationOptionExample example=new TbSpecificationOptionExample();
    	TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
    	criteria.andSpecIdEqualTo(tbspecification.getId());
    	specificationOptionMapper.deleteByExample(example);
    	
    	//获取规格选项集合
    	List<TbSpecificationOption> specificationOptionList = specification.getSpecificationOptionList();
    	for( TbSpecificationOption option:specificationOptionList){
    		option.setSpecId(tbspecification.getId());//设置规格ID
    		specificationOptionMapper.insert(option);//新增规格
    	}
    	
    }	
    
  3. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 修改
     * @param specification
     * @return
     */
    @RequestMapping("/update")
    public Result update(@RequestBody Specification specification){
    	try {
    		specificationService.update(specification);
    		return new Result(true, "修改成功");
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    	return new Result(false, "修改失败");
    }
    
  4. 修改specificationController.js的save方法

    //保存 
    $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);
    			}
    		}		
    	);				
    };
    

删除规格

  1. 思路: 要删除规格的同时,还要记得将关联的规格选项删除掉

  2. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    /**
     * 批量删除
     */
    @Override
    public void delete(Long[] ids) {
    	for(Long id:ids){
    		//删除规格表数据
    		specificationMapper.deleteByPrimaryKey(id);
    		
    		//删除规格选项表数据		
    		TbSpecificationOptionExample example=new TbSpecificationOptionExample();
    		TbSpecificationOptionExample.Criteria criteria = example.createCriteria();
    		criteria.andSpecIdEqualTo(id);
    		specificationOptionMapper.deleteByExample(example);
    	}		
    }
    
  3. 修改页面specification.html

    1. 列表复选框

      <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
      
    2. 删除按钮

      <button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o"></i> 删除</button>
      

测试

  1. 查看规格管理列表

    这里写图片描述

  2. 新建规格,保存成功

    这里写图片描述

    这里写图片描述

  3. 修改规格,保存

    这里写图片描述

  4. 删除规格

    这里写图片描述

模板管理

需求及表结构分析

需求分析
  1. 模板的作用:
    1. 用于关联品牌与规格
    2. 定义扩充属性
表结构分析
  1. tb_type_template 模板表

    字段类型长度含义
    IdBigint主键
    nameVarchar80模板名称
    Spec_idsVarchar1000关联规格(json格式)
    brand_idsVarchar1000关联品牌(json格式)
    custom_attribute_itemsVarchar2000扩展属性

模板列表

引入JS
  1. 修改type_template.html

    <script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
    <script src="../plugins/angularjs/pagination.js"></script>
    <link rel="stylesheet" href="../plugins/angularjs/pagination.css">
    <script type="text/javascript" src="../js/base_pagination.js"></script>
    <script type="text/javascript" src="../js/controller/baseController.js"></script>
    
    <script type="text/javascript" src="../js/service/typeTemplateService.js"></script>
    <script type="text/javascript" src="../js/controller/typeTemplateController.js"></script>
    
加载列表数据
  1. 在body元素指定模块名和控制器名

    <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController">
    
  2. 加载数据,添加分页

    <!--数据列表-->
    <table id="dataList" class="table table-bordered table-striped table-hover dataTable">
        <thead>
        <tr>
            <th class="" style="padding-right:0px">
                <input id="selall" type="checkbox" class="icheckbox_square-blue">
            </th>
            <th class="sorting_asc">模板ID</th>
            <th class="sorting">分类模板名称</th>
            <th class="sorting">关联品牌</th>
            <th class="sorting">关联规格</th>
            <th class="sorting">扩展属性</th>
            <th class="text-center">操作</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="entity in list">
            <td><input type="checkbox"></td>
            <td>{{entity.id}}</td>
            <td>{{entity.name}}</td>
            <td>{{entity.brandIds}}</td>
            <td>{{entity.specIds}}</td>
            <td>{{entity.customAttributeItems}}</td>
            <td class="text-center">
                <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal">修改
                </button>
            </td>
        </tr>
        </tbody>
    </table>
    <!--数据列表/-->
    
    <!-- 分页 -->
    <tm-pagination conf="paginationConf"></tm-pagination>
    

品牌下拉列表

  1. 在新增或修改的弹出窗口中有个品牌下拉列表,要求品牌是可以选择多个。要实现这个功能,需要使用select2组件。

    这里写图片描述

显示品牌下拉列表
  1. 修改type_template.html,引入select JS

    <!-- 引入select2相关的css和js -->
    <link rel="stylesheet" href="../plugins/select2/select2.css">
    <link rel="stylesheet" href="../plugins/select2/select2-bootstrap.css">
    <script type="text/javascript" src="../plugins/select2/select2.min.js"></script>
    <script type="text/javascript" src="../js/angular-select2.js"></script>
    
  2. 修改typeTemplateController.js,定义品牌列表数据

    $scope.brandList={data:[]};//品牌列表 
    
  3. 修改type_template.html,实现select2组件多选下拉框

    <tr>
        <td>关联品牌</td>
        <td>
            <input select2 select2-model="entity.brandIds" config="brandList" multiple placeholder="选择品牌(可多选)" class="form-control" type="text">
        </td>
    </tr>
    
    1. multiple 表示可多选
    2. config 用户配置数据来源
    3. select2-model用于指定用户选择后提交的变量
后端数据支撑
  1. 在pinyougou-dao工程,TbBrandMapper.xml中添加SQL语句

    <select id="selectOptionList" resultType="java.util.Map">
    select id,name as text from tb_brand
    </select>
    
  2. 在pinyougou-dao工程,TbBrandMapper中添加方法定义

    List<Map> selectOptionList();
    
  3. 修改pinyougou-sellergoods-interface的BrandService.java

    /**
     * 品牌下拉框数据
     *
     * @return the list
     */
    List<Map> selectOptionList();
    
  4. 修改pinyougou-sellergoods-service的BrandServiceImpl.java

    @Override
    public List<Map> selectOptionList() {
        return brandMapper.selectOptionList();
    }
    
  5. 修改pinyougou-manager-web的BrandController.java

    /**
     * 下拉列表数据.
     *
     * @return the list
     */
    @RequestMapping("/selectOptionList")
    public List<Map> selectOptionList() {
        return brandService.selectOptionList();
    }
    
  6. 修改webapp下的brandService.js

    // 下拉列表数据
    this.selectOptionList = function () {
        return $http.get("../brand/selectOptionList.do");
    }
    
  7. 修改pinyougou-manager-web的typeTemplateController.js

    1. 依赖注入brandService

      app.controller('typeTemplateController' ,function($scope,$controller, typeTemplateService, brandService, specificationService)
      
    2. 修改品牌服务方法实现查询,结果赋值给变量

      $scope.brandList={data:[]};//品牌列表
          
      //读取品牌列表
      $scope.findBrandList=function(){
      	brandService.selectOptionList().success(
      		function(response){
      			$scope.brandList={data:response};
      		}
      	);		
      }
      
    3. 修改type_template.html,导入js

      <script type="text/javascript" src="../js/service/brandService.js"></script>
      <script type="text/javascript" src="../js/service/specificationService.js"></script>
      <script type="text/javascript" src="../js/service/typeTemplateService.js"></script>
      <script type="text/javascript" src="../js/controller/typeTemplateController.js"></script>
      
    4. 修改type_template.html,添加初始化

      <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController" ng-init="findBrandList()">
      

规格下拉列表

  1. 在新增或修改的弹出窗口中规格下拉列表,要求品牌是可以选择多个。

    这里写图片描述

显示规格下拉列表
  1. 修改typeTemplateController.js,定义规格列表数据

    $scope.specList={data:[]};//规格列表
    
  2. 修改type_template.html,实现select2组件多选下拉框

    <tr>
        <td>关联规格</td>
        <td>
            <input select2 select2-model="entity.specIds" config="specList" multiple placeholder="选择规格(可多选)" class="form-control" type="text">
        </td>
    </tr>
    
    1. multiple 表示可多选
    2. config 用户配置数据来源
    3. select2-model用于指定用户选择后提交的变量
后端数据支撑
  1. 在pinyougou-dao工程,TbSpecificationMapper.xml中添加SQL语句

    <select id="selectOptionList" resultType="java.util.Map">
        select id,spec_name as text from tb_specification
    </select>
    
  2. 在pinyougou-dao工程,TbSpecificationMapper中添加方法定义

    List<Map> selectOptionList();
    
  3. 修改pinyougou-sellergoods-interface的SpecificationService.java

    /**
     * 规格下拉列表
     *
     * @return the list
     */
    public List<Map> selectOptionList();
    
  4. 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

    @Override
    public List<Map> selectOptionList() {
    
    	return specificationMapper.selectOptionList();
    }
    
  5. 修改pinyougou-manager-web的SpecificationController.java

    /**
     * 规格下拉列表.
     *
     * @return the list
     */
    @RequestMapping("/selectOptionList")
    public List<Map> selectOptionList(){
    	return specificationService.selectOptionList();
    }
    
  6. 修改webapp下的specificationService.js

    //下拉列表
    this.selectOptionList=function(){
    	return $http.get('../specification/selectOptionList.do');
    }
    
  7. 修改pinyougou-manager-web的typeTemplateController.js

    1. 依赖注入specificationService

      app.controller('typeTemplateController' ,function($scope,$controller, typeTemplateService, brandService, specificationService)
      
    2. 修改规格服务方法实现查询,结果赋值给变量

      $scope.specList={data:[]};//规格列表
      	
      //读取规格列表
      $scope.findSpecList=function(){
      	specificationService.selectOptionList().success(
      			function(response){
      				$scope.specList={data:response};
      			}
      	);		
      }
      
    3. 修改type_template.html,添加初始化

      <body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController" ng-init="findBrandList();findSpecList()">
      

扩展属性

增加行
  1. 在typeTemplateController.js中新增代码

    //增加扩展属性行
    $scope.addTableRow=function(){
    	$scope.entity.customAttributeItems.push({});
    };
    
  2. 修改type_template.html的“新建”按钮

    <button type="button" class="btn btn-default" title="新建" data-toggle="modal"
            data-target="#editModal" ng-click="entity={customAttributeItems:[]}"><i class="fa fa-file-o"></i> 新建
    </button>
    
  3. 加载数据

    <tr ng-repeat="pojo in entity.customAttributeItems">
        <td><input type="checkbox" class="icheckbox_square-blue"></td>
        <td><input class="form-control" placeholder="属性名称" ng-model="pojo.text"></td>
        <td>
            <button type="button" class="btn btn-default" title="删除"><i
                    class="fa fa-trash-o"></i> 删除
            </button>
        </td>
    </tr>
    
删除行
  1. 思路:在每一行将索引值传递给集合,在集合中删除。

  2. 修改typeTemplateController.js新增以下代码

    //删除扩展属性行
    $scope.deleTableRow=function(index){
    	$scope.entity.customAttributeItems.splice( index,1);
    }
    
  3. 修改每行的删除按钮

    <td>
        <button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i
                class="fa fa-trash-o"></i> 删除
        </button>
    </td>
    

新增模板

  1. 修改type_template.html, 绑定名称

    <tr>
        <td>商品类型</td>
        <td><input class="form-control" placeholder="商品类型" ng-model="entity.name"></td>
    </tr>
    
  2. 保存事件

    <button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>
    

修改模板

  1. 修改typeTemplateController.js

    // 查询实体 
    $scope.findOne=function(id){				
    	typeTemplateService.findOne(id).success(
    		function(response){
    			$scope.entity= response;		
    			
    			//转换字符串为json对象(集合)
    			$scope.entity.brandIds=  JSON.parse( $scope.entity.brandIds);
    			$scope.entity.specIds= JSON.parse($scope.entity.specIds);
    			$scope.entity.customAttributeItems = JSON.parse($scope.entity.customAttributeItems);
    			
    		}
    	);				
    };
    
  2. 修改按钮

    <td class="text-center">
        <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改
        </button>
    </td>
    

删除模板

  1. 修改type_template.html的复选框

    <tr ng-repeat="entity in list">
        <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
        <td>{{entity.id}}</td>
        <td>{{entity.name}}</td>
        <td>{{entity.brandIds}}</td>
        <td>{{entity.specIds}}</td>
        <td>{{entity.customAttributeItems}}</td>
        <td class="text-center">
            <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改
            </button>
        </td>
    </tr>
    
  2. 保存事件

    <button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o"></i> 删除</button>
    

优化模板列表的显示

  1. 修改baseController.js

    // 定义方法:获取JSON字符串中的某个key对应值的集合
    $scope.jsonToString = function(jsonStr,key){
        // 将字符串转成JSOn:
        var jsonObj = JSON.parse(jsonStr);
    
        var value = "";
        for(var i=0;i<jsonObj.length;i++){
    
            if(i>0){
                value += ",";
            }
    
            value += jsonObj[i][key];
        }
        return value;
    };
    
  2. 修改type_template.html

    <tr ng-repeat="entity in list">
        <td><input type="checkbox" ng-click="updateSelection($event, entity.id)"></td>
        <td>{{entity.id}}</td>
        <td>{{entity.name}}</td>
        <td>{{jsonToString(entity.brandIds, 'text')}}</td>
        <td>{{jsonToString(entity.specIds, 'text')}}</td>
        <td>{{jsonToString(entity.customAttributeItems, 'text')}}</td>
        <td class="text-center">
            <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)">修改
            </button>
        </td>
    </tr>
    

测试

  1. 刷新页面,查看页面显示不为json

    这里写图片描述

  2. 新增模板,能够保存成功

    这里写图片描述

    这里写图片描述

  3. 修改

    这里写图片描述

    这里写图片描述

  4. 删除

    这里写图片描述

    这里写图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄旺鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值