- 视频教程:【黑马程序员】Java大型电商项目—品优购【配套源码+笔记】_哔哩哔哩_bilibili
- 源码下载:
- 链接:https://pan.baidu.com/s/1fECz5In_XCB-aW6ed6ZTbA
- 提取码:27xa
技术选型:
后端框架:Spring+SpringMVC+mybatis+Dubbox
前端:angularJS+Bootstrap
- 分布式:Dubbox框架
- 注册中心:Zookeeper
前端出错,先清理一下浏览器的缓存,再刷新一下页面,,还是报错,再去看代码
运行环境
1、linux虚拟机
- 运行linux虚拟机
- 打开linux的终端,不可关闭虚拟机
- 打开SecureCRT代替linux的终端写命令,更清楚
- 启动zookeeper
- cd
- cd zookeeper-3.4.6
- cd bin
- ./zkServer.sh start
- ./zkServer.sh status 查看zookeeper运行状态,是否开启了
- 每次重启虚拟机,ip地址会发生变化,所以把虚拟机挂起就行,不用关机
- 查看ip地址的命令:ifconfig
- 如果ip地址变化,则相应地修改springmvc.xml文件里的zookeeper信息。2181是zookeeper的默认端口,如果配置文件里没有改动,就不变
- 后续写代码时,在浏览器访问html文件时,不报错,但就是不显示表格,除了表格什么都正常,很难排错。后来发现是zookeeper的端口发生了变化,但是代码里没有修改过来。
2、mysql数据库
- mysql如何导入.sql文件:http://t.csdnimg.cn/mhP9M
- 保持打开状态,才可运行其他代码
后端:在IDEA上搭建工程
1、先建父工程,后建子模块
2、引入依赖
- 主要问题:
- 有些依赖maven的本地仓库里没有,需要手动导入
- 解决教程:http://t.csdnimg.cn/m4fCs
- 有些依赖的版本需要修改,比如dubbo的2.8.4版本已经不维护了,要改成2.5.3;还有mysql的版本也要和自己电脑里8.0版本的mysql相对应,不能用5.0版本的。
- 解决办法:只需对着pom.xml文件里的依赖在maven的本地仓库里逐个寻找,把爆红的依赖版本改成仓库里现有的依赖版本
- 父工程的pom.xml文件需要手动导入的jar包命令如下
mvn install:install-file -Dfile=D:\各种jar包\fastdfs-client-java-1.29.jar -DgroupId=org.csource -DartifactId=fastdfs-client-java -Dversion=1.29 -Dpackaging=jar
mvn install:install-file -Dfile=D:\各种jar包\spring-security-cas-4.1.0.RELEASE.jar -DgroupId=org.springframework.security -DartifactId=spring-security-cas -Dversion=4.1.0.RELEASE -Dpackaging=jar
mvn install:install-file -Dfile=D:\各种jar包\cas-client-core-3.5.1.jar -DgroupId=org.jasig.cas.client -DartifactId=cas-client-core -Dversion=3.3.3 -Dpackaging=jar
mvn install:install-file -Dfile=D:\各种jar包\kaptcha-2.3.2.jar -DgroupId=com.github.penggle -DartifactId=kaptcha -Dversion=2.3.2 -Dpackaging=jar
mvn install:install-file -Dfile=D:\各种jar包\solr-solrj-4.10.3.jar -DgroupId=org.apache.solr -DartifactId=solr-solrj -Dversion=4.10.3 -Dpackaging=jar
mvn install:install-file -Dfile=D:\各种jar包\activemq-all-5.11.2.jar -DgroupId=org.apache.activemq -DartifactId=activemq-all -Dversion=5.11.2 -Dpackaging=jar
mvn install:install-file -Dfile=D:\各种jar包\ikanalyzer-2012_u6.jar -DgroupId=com.janeluo -DartifactId=ikanalyzer -Dversion=2012_u6 -Dpackaging=jar
3、逆向工程
- 目的:实现实体类与数据访问层代码的自动生成
- 老师发的资料里没有逆向工程的最新代码,把旧的代码修改一下,即可用,具体代码已放资源里
- 修改的地方主要有
- 1、mapper映射文件的生成位置
- 2、数据库的连接密码
逆向代码运行教程:http://t.csdnimg.cn/Qt5ti
没有逆向工程源码也行,直接从老师发的资料里其他源码里拿到pojo包,接口包和mapper映射文件包三个包即可
容易出现的问题:逆向工程的代码生错了,要仔细辨别
4、编写后端代码
- 注意@Service和@Refrence(远程调用)注解引入要用dubbo的,否则会注入失败,报空指针异常
- import com.alibaba.dubbo.config.annotation.Reference;
- import com.alibaba.dubbo.config.annotation.Service;
5、测试
前端:框架AngularJS
四大特性
- 1、MVC模式
- 2、双向绑定
- 3、依赖注入
- 4、模块化设计
基本内容
- 表达式
angularJS demo 表达式 {{100+100}}- 双向绑定
angularJS demo 双向绑定 请输入你的名称: {{myname}},你好- 初始化指令
angularJS demo 初始化指令 请输入你的名称: {{myname}},你好- 控制器
angularJS demo 控制器 x: y: {{add()}}- 事件指令
angularJS demo 事件指令 x: y: {{z}}- 循环数组
angularJS demo 循环数组
{{x}} - 循环对象数组
angularJS demo 循环对象数组
{{x.name}} {{x.chinese}} {{x.math}} - 内置服务
angularJS demo 内置服务
{{x.name}} {{x.chinese}} {{x.math}} //json数据 [ // key用双引号括起,value若是字符串也要用双引号括起 {"name":"张三","chinese":1,"math":1}, {"name":"李四","chinese":2,"math":2}, {"name":"王五","chinese":3,"math":3}, {"name":"赵六","chinese":4,"math":4} ]
常用指令
- ng-app:定义AngularJS应用程序的根元素
- ng-model:用于绑定变量(输入端和变量端,双向绑定)
- ng-init:初始化变量
- ng-controller:用于指定所用控制器
- ng-click:单击事件指令,点击时触发控制器的某个方法
- ng-repeat:用于循环数组变量
pinyougou-pojo模块
package entity;
import java.io.Serializable;
import java.util.List;
/**
* 分布结果实体类
* 模块:pinyougou-pojo
* 路径:src/main/java/entity
*/
public class PageResult implements Serializable {
private long total;//记录总条数
private List rows;//当面页记录
//getter,setter方法和构造器省略
}
pinyougou-sellergoods-interface模块
package com.pinyougou.sellergoods.service;
import com.pinyougou.pojo.TbBrand;
import entity.PageResult;
import java.util.List;
/**
* 品牌业务接口
*/
public interface BrandService {
/**
* 分布查询
* @param pageNum
* @param pageSize
* @return
*/
public PageResult findPage(int pageNum,int pageSize);
}
pinyougou-sellergoods-service模块
package com.pinyougou.sellergoods.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* 品牌服务层实现类
*/
@Service
public class BrandServiceImpl implements BrandService {
/**
* 分页的服务层代码
* @param pageNum
* @param pageSize
* @return
*/
@Override
public PageResult findPage(int pageNum, int pageSize) {
PageHelper.startPage(pageNum,pageSize);//分页插件
Page page=(Page)brandMapper.selectByExample(null);
//使用分页可以简化前端工作量,不必返回全部内容
return new PageResult(page.getTotal(),page.getResult());
}
}
pinyougou-manager-web模块
package com.pinyougou.manager.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 品牌的控制器层
*/
public class BrandController {
@RequestMapping("/findPage")
public PageResult findPage(int page,int rows){
return brandService.findPage(page,rows);
}
}
父工程重新install后,运行结果:
{{entity.id}}
{{entity.name}}
{{entity.firstChar}}
运行结果:
pinyougou-sellergoods-interface
package com.pinyougou.sellergoods.service;
import com.pinyougou.pojo.TbBrand;
import entity.PageResult;
import java.util.List;
/**
* 品牌业务接口
*/
public interface BrandService {
/**
* 增加品牌
* @param brand
*/
public void add(TbBrand brand);
}
pinyougou-sellergoods-service
package com.pinyougou.sellergoods.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* 品牌服务层实现类
*/
@Service
public class BrandServiceImpl implements BrandService {
/**
* 增加品牌
* @param brand
*/
@Override
public void add(TbBrand brand) {
brandMapper.insert(brand);
}
}
pinyougou-manager-web
package com.pinyougou.manager.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 品牌的控制器层
*/
@RestController
@RequestMapping("/brand")
public class BrandController {
//增加品牌
@RequestMapping("/add")
public Result add(@RequestBody TbBrand brand){
try {
brandService.add(brand);
return new Result(true,"添加成功☺");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"添加失败");
}
}
}
pinyougou-pojo
package entity;
import java.io.Serializable;
/**
* 增加品牌的返回结果实体类
*/
public class Result implements Serializable {
private boolean success;
private String message;
//getter,setter方法,构造器省略
}
品牌ID
品牌名称
品牌首字母
操作
运行结果:
pinyougou-sellergoods-interface
package com.pinyougou.sellergoods.service;
import com.pinyougou.pojo.TbBrand;
import entity.PageResult;
import java.util.List;
/**
* 品牌业务接口
*/
public interface BrandService {
/**
* 根据ID查询实体
* @param id
* @return
*/
public TbBrand findOne(Long id);
/**
* 修改
* @param brand
*/
public void update(TbBrand brand);
}
pinyougou-sellergoods-service
package com.pinyougou.sellergoods.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* 品牌服务层实现类
*/
@Service
public class BrandServiceImpl implements BrandService {
//根据ID查询
@Override
public TbBrand findOne(Long id) {
return brandMapper.selectByPrimaryKey(id);
}
//修改
@Override
public void update(TbBrand brand) {
brandMapper.updateByPrimaryKey(brand);
}
}
pinyougou-manager-web
package com.pinyougou.manager.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 品牌的控制器层
*/
public class BrandController {
//根据ID查询
@RequestMapping("/findOne")
public TbBrand findOne(Long id){
return brandService.findOne(id);
}
//修改
@RequestMapping("/update")
public Result update(@RequestBody TbBrand brand){
try {
brandService.update(brand);
return new Result(true,"修改成功☺");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"修改失败");
}
}
}
运行结果:
{{entity.id}}
{{entity.name}}
{{entity.firstChar}}
运行结果:
pinyougou-sellergoods-interface
package com.pinyougou.sellergoods.service;
import com.pinyougou.pojo.TbBrand;
import entity.PageResult;
import java.util.List;
/**
* 品牌业务接口
*/
public interface BrandService {
/**
* 删除
* @param ids
*/
public void delete(Long []ids);
}
pinyougou-sellergoods-service
package com.pinyougou.sellergoods.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* 品牌服务层实现类
*/
@Service
public class BrandServiceImpl implements BrandService {
//删除
@Override
public void delete(Long[] ids) {
for(Long id:ids){
brandMapper.deleteByPrimaryKey(id);
}
}
}
pinyougou-manager-web
package com.pinyougou.manager.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 品牌的控制器层
*/
@RestController
@RequestMapping("/brand")
public class BrandController {
//删除
@RequestMapping("/delete")
public Result delete(Long []ids){
try {
brandService.delete(ids);
return new Result(true,"删除成功☺");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"删除失败");
}
}
}
运行结果:
{{selectIds}}
pinyougou-sellergoods-interface
package com.pinyougou.sellergoods.service;
import com.pinyougou.pojo.TbBrand;
import entity.PageResult;
import java.util.List;
/**
* 品牌业务接口
*/
public interface BrandService {
/**
* 条件查询
* @param pageNum
* @param pageSize
* @return
*/
//直接传递一个实体类TbBrand比逐个传递它的属性要更灵活
public PageResult findPage(TbBrand brand,int pageNum,int pageSize);
}
pinyougou-sellergoods-service
package com.pinyougou.sellergoods.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pinyougou.mapper.TbBrandMapper;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.pojo.TbBrandExample;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/**
* 品牌服务层实现类
*/
@Service
public class BrandServiceImpl implements BrandService {
//条件查询
@Override
public PageResult findPage(TbBrand brand, int pageNum, int pageSize) {
//分页插件
PageHelper.startPage(pageNum,pageSize);
//封装查询条件
TbBrandExample example = new TbBrandExample();
//构建查询条件的类
TbBrandExample.Criteria criteria = example.createCriteria();
if(brand!=null){
//如果有名称的条件
if(brand.getName()!=null && brand.getName().length() > 0){
//where name like %s%
criteria.andNameLike("%"+brand.getName()+"%");
}
//如果有首字母的条件
if(brand.getFirstChar()!=null && brand.getFirstChar().length() > 0){
criteria.andFirstCharEqualTo(brand.getFirstChar());
}
}
Page page=(Page)brandMapper.selectByExample(null);
return new PageResult(page.getTotal(),page.getResult());
}
}
pinyougou-manager-web
package com.pinyougou.manager.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.pinyougou.pojo.TbBrand;
import com.pinyougou.sellergoods.service.BrandService;
import entity.PageResult;
import entity.Result;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 品牌的控制器层
*/
@RestController
@RequestMapping("/brand")
public class BrandController {
//条件查询
@RequestMapping("/search")
public PageResult search(@RequestBody TbBrand brand, int page,int rows){
return brandService.findPage(brand,page,rows);
}
}
名称:
首字母:
运行结果:
//使用分页插件时,引入该资源
var app=angular.module("pinyougou",["pagination"]);
//不使用分页插件时,引入该资源
var app=angular.module("pinyougou",[]);
//构建前端服务层
//和后端打交道的代码写在服务层
app.service("brandService",function($http){
//$get:传递属性,变量; $post:传递对象
this.findAll=function () {
return $http.get('../brand/findAll.do');
}
this.findPage=function (page,rows) {
return $http.get("../brand/findPage.do?page="+page+"&rows="+rows);
}
this.search=function (page,rows,searchEntity) {
return $http.post("../brand/search.do?page="+page+"&rows="+rows,searchEntity);
}
this.add=function (entity) {
return $http.post("../brand/add.do?",entity);
}
this.update=function (entity) {
return $http.post("../brand/update.do?",entity);
}
this.findOne=function (id) {
return $http.get("../brand/findOne.do?id="+id);
}
this.dele=function (ids) {
return $http.get("../brand/delete.do?ids="+ids);
}
})
//构建前端的控制层
//和页面打交道的代码写在控制层
app.controller("brandController",function ($scope,brandService) {
//读取列表数据绑定到表单中
$scope.findAll=function () {
brandService.findAll().success(function(response){
$scope.list=response;
})
}
//定义搜索对象
$scope.searchEntity={};
//条件查询+分页
$scope.search=function(page,rows){
brandService.search(page,rows,$scope.searchEntity).success(function (response) {
$scope.list=response.rows;//给列表变量赋值
$scope.paginationConf.totalItems=response.total;//定义总记录数
})
}
//分页
$scope.findPage=function(page,rows) {
brandService.findPage(page,rows).success(function(response){
$scope.list=response.rows;
$scope.paginationConf.totalItems=response.total;//定义总记录数
})
}
//定义对象paginationConf,分布的配置
$scope.paginationConf={
currentPage: 1,//当前页
totalItems: 10,//总记录条数
itemsPerPage: 10,//每页的记录条数
perPageOptions: [10,20,30,40,50],//页码选项,每页10条还是20还是...
onChange: function () {//当页码发生变化时自动触发的方法
$scope.reloadList();
}
}
//重新加载记录
$scope.reloadList=function () {
$scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}
//保存(新增和修改)
$scope.save=function () {
var object=null;
//新增时,id为空;但修改时,id不为空
if($scope.entity.id!=null){
object=brandService.update($scope.entity);
}else{
object=brandService.add($scope.entity);
}
object.success(function(response){
if(response.success){
$scope.reloadList();//刷新数据
}else{
alert(response.message);//打印信息
}
})
}
//根据ID查询
$scope.findOne=function(id){
brandService.findOne(id).success(function (response) {
$scope.entity=response;
})
}
//批量选中
$scope.selectIds=[];//选中的ID数组,准备批量删除的数据
$scope.updateSelection=function($event,id){
if($event.target.checked){//判断是否选中
$scope.selectIds.push(id);//向数组中添加数据
}else{
var idx=$scope.selectIds.indexOf(id);//id在选中数据的数组中的位置
$scope.selectIds.splice(idx,1);//从数组中删除数据,重复点复选框,选择和取消选择反复横跳
}
}
//删除
$scope.dele=function () {
brandService.dele($scope.selectIds).success(function (response) {
if(response.success){
$scope.reloadList();//刷新列表
$scope.selectIds=[];
}else{
alert(response.message);//打印信息
}
})
}
})
//父控制器
app.controller("baseController",function ($scope) {
//定义搜索对象
$scope.searchEntity={};
//定义对象paginationConf,分布的配置
$scope.paginationConf={
currentPage: 1,//当前页
totalItems: 10,//总记录条数
itemsPerPage: 10,//每页的记录条数
perPageOptions: [10,20,30,40,50],//页码选项,每页10条还是20还是...
onChange: function () {//当页码发生变化时自动触发的方法
$scope.reloadList();
}
}
//重新加载记录
$scope.reloadList=function () {
$scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}
//批量选中
$scope.selectIds=[];//选中的ID数组,准备批量删除的数据
$scope.updateSelection=function($event,id){
if($event.target.checked){//判断是否选中
$scope.selectIds.push(id);//向数组中添加数据
}else{
var idx=$scope.selectIds.indexOf(id);//id在选中数据的数组中的位置
$scope.selectIds.splice(idx,1);//从数组中删除数据,重复点复选框,选择和取消选择反复横跳
}
}
})
//构建前端的控制层
//和页面打交道的代码写在控制层
app.controller("brandController",function ($scope,$controller,brandService) {
//把baseController的$scope传递给brandController的$scope,伪继承
$controller("baseController",{$scope:$scope});
//读取列表数据绑定到表单中
$scope.findAll=function () {
brandService.findAll().success(function(response){
$scope.list=response;
})
}
//条件查询+分页
$scope.search=function(page,rows){
brandService.search(page,rows,$scope.searchEntity).success(function (response) {
$scope.list=response.rows;//给列表变量赋值
$scope.paginationConf.totalItems=response.total;//定义总记录数
})
}
//分页
$scope.findPage=function(page,rows) {
brandService.findPage(page,rows).success(function(response){
$scope.list=response.rows;
$scope.paginationConf.totalItems=response.total;//定义总记录数
})
}
//保存(新增和修改)
$scope.save=function () {
var object=null;
//新增时,id为空;但修改时,id不为空
if($scope.entity.id!=null){
object=brandService.update($scope.entity);
}else{
object=brandService.add($scope.entity);
}
object.success(function(response){
if(response.success){
$scope.reloadList();//刷新数据
}else{
alert(response.message);//打印信息
}
})
}
//根据ID查询
$scope.findOne=function(id){
brandService.findOne(id).success(function (response) {
$scope.entity=response;
})
}
//删除
$scope.dele=function () {
brandService.dele($scope.selectIds).success(function (response) {
if(response.success){
$scope.reloadList();//刷新列表
$scope.selectIds=[];
}else{
alert(response.message);//打印信息
}
})
}
})
写代码的思路、逻辑、顺序基本如下
/**
* 下拉列表数据
* @return
*/
List
public List
@Override
public List
@RequestMapping("/selectOptionList")
public List
运行结果:
this.selectOptionList=function () {
return $http.get("../brand/selectOptionList.do")
}
//控制层
app.controller('typeTemplateController' ,function($scope,$controller,typeTemplateService,brandService,specificationService){
$controller('baseController',{$scope:$scope});//继承
//搜索
$scope.search=function(page,rows){
typeTemplateService.search(page,rows,$scope.searchEntity).success(
function(response){
$scope.list=response.rows;
$scope.paginationConf.totalItems=response.total;//更新总记录数
}
);
}
$scope.brandList={data:[]};//品牌列表
//查询品牌列表
$scope.findBrandList=function(){
brandService.selectOptionList().success(
function(response){
$scope.brandList={data:response};
}
);
}
});
{{entity.id}}
{{entity.name}}
{{entity.brandIds}}
{{entity.specIds}}
{{entity.customAttributeItems}}
运行结果:
规格下拉列表(同上)
注意事项:
typeTemplate.html文件里的ng-init必须带上findAll()方法,用浏览器访问时才会正常显示表格
//增加扩展属性行
$scope.addTableRow=function(){
$scope.entity.customAttributeItems.push({});
}
//删除扩展属性行
$scope.deleTableRow=function(index){
$scope.entity.customAttributeItems.splice(index,1);
}
运行结果:
1、绑定文本框
2、保存按钮
运行结果:
//查询实体
$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);//自定义属性
// JSON.parse(string): 将字符串转成对象
// JSON.stringify(object): 将对象转成字符串
}
);
}
修改按钮
1、复选框勾选
{{entity.id}}
{{entity.name}}
{{entity.brandIds}}
{{entity.specIds}}
{{entity.customAttributeItems}}
2、删除按钮
运行结果:
//提取json字符串数据中某个属性,返回拼接字符串,逗号分隔
// 让浏览器访问的html文件上的数据更通俗易懂
$scope.jsonToString=function (jsonString,key) {
var json=JSON.parse(jsonString);
var value="";
for(var i=0;i0){//第一个值前面不用加逗号分隔
value+=",";//使用逗号分隔
}
value+=json[i][key];//key是json[i]的某个属性
}
return value;
}
{{entity.id}}
{{entity.name}}
{{ jsonToString(entity.brandIds,"text") }}
{{ jsonToString(entity.specIds,"text") }}
{{ jsonToString(entity.customAttributeItems,"text") }}
优化前:
优化后:
经常出现的问题:
如果出现更改了前端代码,前端代码没有问题,但前端页面显示不正常(一般是规定的数据不显示),就清除一下浏览器的数据(另外去百度),再刷新一下页面
public List findByParentId(Long parentId);
@Override
public List findByParentId(Long parentId) {
TbItemCatExample example = new TbItemCatExample();
TbItemCatExample.Criteria criteria = example.createCriteria();
criteria.andParentIdEqualTo(parentId);
return tbItemCatMapper.selectByExample(example);
}
/**
* 根据上级ID查询商品分类
* @param parentId
* @return
*/
@RequestMapping("/findByParentId")
public List findByParentId(Long parentId){
return itemCatService.findByParentId(parentId);
}
运行结果:
//根据上级ID查询列表
this.findByParentId=function (parentId) {
return $http.get('../itemCat/findByParentId.do?parentId='+parentId);
}
//根据上级ID查询列表
$scope.findByParentId=function (parentId) {
itemCatService.findByParentId(parentId).success(
function (response) {
$scope.list=response;
}
);
}
{{entity.id}}
{{entity.name}}
{{entity.typeId}}
运行结果:
面包屑导航(Breadcrumb Navigation)这个概念来自童话故事“汉赛尔和格莱特”,当汉赛尔和格莱特穿过森林时,不小心迷路了,但是他们发现沿途走过的地方都撒下了面包屑,让这些面包屑来帮助他们找到回家的路。
//定义面包屑
$scope.breadcrumb=[{id:0,name:"顶级分类列表"}];
$scope.search=function (id,name) {
//添加面包屑
$scope.breadcrumb.push({id:id,name:name});
$scope.findByParentId(id);
}
$scope.showList=function (index,id) {
//截断面包屑
//index+1: 表示从当前索引的后一个索引开始截断(从面包屑中去除)
//2: 表示截断的个数,在此最大是3级,所以写2,写100也没关系
$scope.breadcrumb.splice(index+1,2);
$scope.findByParentId(id);
}
1、查询下级按钮
2、绑定面包屑
运行结果:
在哪一级新增商品分类,那新增数据就应该显示在哪一级,而不是全部显示在顶级。
关键在于查询时记录下当前级parentId
//保存
$scope.save=function(){
var serviceObject;//服务层对象
if($scope.entity.id!=null){//如果有ID
serviceObject=itemCatService.update( $scope.entity ); //修改
}else{
serviceObject=itemCatService.add( $scope.entity );//增加
}
serviceObject.success(
function(response){
if(response.success){
//重新查询
$scope.findByParentId($scope.entity.parentId);
}else{
alert(response.message);
}
}
);
}
$scope.searchEntity={};//定义搜索对象
//定义变量parentId,记录本级的ID
//entity是表单所绑定的实体
// $socpe.entity={parentId:0};
//根据上级ID查询列表
$scope.findByParentId=function (parentId) {
//查询时记录上级ID
$scope.entity={parentId:parentId};
itemCatService.findByParentId(parentId).success(
function (response) {
$scope.list=response;
}
);
}
上级商品分类
{{pojo.name}}
商品分类名称
类型模板
注意:
itemCatController.js文件去除了 $socpe.entity={parentId:0}; 这句给parentId赋初值的语句,因为parentId后续在function函数中再次被修改,这两个操作会发生冲突,导致前端引用$scope.entity对象时出错,如果要修改,最好使用深拷贝,而非直接赋值
运行结果:
//查询模板列表 (下拉框显示模板)
$scope.findTypeTemplateList=function () {
typeTemplateService.findAll().success(function (response) {
$scope.typeTemplateList=response;//模板列表
})
}
类型模板
运行结果:
/**
* 批量删除
*/
@Override
public void delete(Long[] ids) {
for(Long id:ids){
List list=findByParentId(id);
if(list.size()>0){//要删除的商品有下级商品分类,抛出运行时异常
throw new RuntimeException("不能删除有下级分类的商品分类!");
}else{
//删除
tbItemCatMapper.deleteByPrimaryKey(id);
}
}
}
@RequestMapping("/delete")
public Result delete(Long [] ids){
try {
itemCatService.delete(ids);
return new Result(true, "删除成功");
} catch(RuntimeException e){//把抛出的运行时异常信息打印出来
e.printStackTrace();
return new Result(false,e.getMessage());
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "删除失败");
}
}
//批量删除
$scope.dele=function(){
//获取选中的复选框
itemCatService.dele( $scope.selectIds ).success(
function(response){
if(response.success) {
$scope.findByParentId($scope.entity.parentId);
$scope.selectIds = [];
}else{
alert(response.message);//把异常信息显示在前端页面
}
}
);
}
1、复选框,实现多选
2、删除按钮
//定义一个变量
$scope.typeTemplateMap=[];
//查询模板列表 (下拉框显示模板)
$scope.findTypeTemplateList=function () {
typeTemplateService.findAll().success(function (response) {
$scope.typeTemplateList=response;//模板列表
//构建模板数据,用于列表显示名称
for(var i=0;i<$scope.typeTemplateList.length;i++){
//得到一个对象
var typeTemplate=$scope.typeTemplateList[i];
//把对象的id值修改成name
$scope.typeTemplateMap[typeTemplate.id]=typeTemplate.name;
}
})
}
{{entity.id}}
{{entity.name}}
{{typeTemplateMap[entity.typeId]}}
运行结果: