品牌管理
AngularJS简介
AngularJS 诞生于2009年,后为Google所收购。是一款优秀的前端JS框架,
AngularJS四大特征
MVC模式 双向绑定 依赖注入 模块化设计
一:入门小demo
1.表达式
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>angularjs入门小Demo-1 表达式</title>
<script src="angular.min.js"></script>
</head>
<body ng-app>
{{100+100}}
</body>
</html>
2.双向绑定
<!DOCTYPE html>
<html>
<head>
<title>angularjs入门小Demo-2 双向绑定</title>
<script src="angular.min.js"></script>
</head>
<body ng-app>
请输入你的姓名<input ng-model="name">
{{name}}:你好
</body>
</html>
3.初始化指令
<!DOCTYPE html>
<html>
<head>
<title>angularjs入门小Demo-3 初始化</title>
<script src="angular.min.js"></script>
</head>
<body ng-app ng-init="name='新手' ">
请输入你的姓名<input ng-model="name">
{{name}}:你好
</body>
</html>
4.控制器
<!DOCTYPE html>
<html>
<head>
<title>angularjs入门小Demo-4 控制器</title>
<script src="angular.min.js"></script>
<script>
//建立模块 []是用来引入其他模块的
var app=angular.module("myApp",[]);
//创建控制器 $scope就是控制器和视图层直接交换数据的桥梁
app.controller("myController",function($scope){
$scope.add=function(){
return parseInt($scope.x)+parseInt($scope.y)
}
})
</script>
</head>
<body ng-app="myApp" ng-controller="myController">
第一个数字<input ng-model="x"> 第二个数字<input ng-model="y">
{{add()}}
</body>
</html>
5.事件指令
<!DOCTYPE html>
<html>
<head>
<title>angularjs入门小Demo-5 事件指令</title>
<script src="angular.min.js"></script>
<script>
var app=angular.module("myApp",[]);
app.controller("myController",function($scope){
$scope.add=function(){
$scope.z=parseInt($scope.x)+parseInt($scope.y)
}
})
</script>
</head>
<body ng-app="myApp" ng-controller="myController">
第一个数字<input ng-model="x"> 第二个数字<input ng-model="y">
<button ng-click="add()">运算</button>
运算结果:{{z}}
</body>
</html>
6.循环数组
<html>
<head>
<title>入门小Demo-6 循环数组</title>
<script src="angular.min.js"></script>
<script>
var app=angular.module('myApp',[]);
app.controller('myController',function($scope){
$scope.list=[100,200,300,400];
});
</script>
</head>
<body ng-app="myApp" ng-controller="myController">
<table>
<tr ng-repeat="x in list">
<td>{{x}}</td>
</tr>
</table>
</body>
</html>
7.循环对象数组
<html>
<head>
<title>入门小Demo-6 循环数组</title>
<script src="angular.min.js"></script>
<script>
var app=angular.module('myApp',[]);
app.controller('myController',function($scope){
$scope.list=[
{name:"张三",age:18},
{name:"李四",age:20},
{name:"王五",age:16},
{name:"赵六",age:22},
];
});
</script>
</head>
<body ng-app="myApp" ng-controller="myController">
<table>
<tr>
<td>姓名</td>
<td>年龄</td>
</tr>
<tr ng-repeat="entity in list">
<td>{{entity.name}}</td>
<td>{{entity.age}}</td>
</tr>
</table>
</body>
</html>
8.内置服务 $http.get("请求的地址")
我们的数据一般都是从后端获取的,那么如何获取数据呢?我们一般使用内置服务$http来实现。注意:以下代码需要在tomcat中运行。
<!DOCTYPE html>
<html>
<head>
<title>angularjs入门小Demo-8 内置服务$http</title>
<script src="angular.min.js"></script>
<script>
var app=angular.module("myApp",[]);
app.controller("myController",function($scope,$http){
$scope.findAll=function(){
$http.get("./data.json").success(
function(response){
$scope.list=response;
});
}
});
</script>
</head>
<body ng-app="myApp" ng-controller="myController" ng-init="findAll()">
<table>
<tr>
<td>姓名</td>
<td>年龄</td>
</tr>
<tr ng-repeat="entity in list">
<td>{{entity.name}}</td>
<td>{{entity.age}}</td>
</tr>
</table>
</body>
</html>
data.json
[
{"name":"张三","age":18},
{"name":"李四","age":20},
{"name":"王五","age":16},
{"name":"赵六","age":22}
]
二:实现品牌列表的查询(不用分页和条件查询)效果如下:
<script src="../plugins/angularjs/angular.min.js"></script>
<script>
var app=angular.module("pinyougou",[]);
app.controller("brandController",function($scope,$http){
$scope.findAll=function(){
$http.get("../brand/findAll.do").success(
function(response){
$scope.list=response;
});
}
});
</script>
<body class="hold-transition skin-red sidebar-mini"
ng-app="pinyougou" ng-controller="brandController" ng-init="findAll()">
<tr ng-repeat="entity in list">
<td><input type="checkbox" ></td>
<td>{{entity.id}}</td>
<td>{{entity.name}}</td>
<td>{{entity.firstChar}}</td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" >修改</button>
</td>
</tr>
三:品牌列表分页的实现
后端给前端的数据
总记录数 total
当前页显示的数据 rows
{total:100,rows:[ ] }
方法一:
Map map=new HashMap();
map.put('total',100);
map.put('rows',list);
return map;
方法二:
创建类 包含total 和 rows 属性
前端给后端的数据 当前页 当前页显示的条数
public class PageResult implements Serializable{
private long total;//总记录数
private List rows;//当前页结果
public PageResult(long total, List rows) {
super();
this.total = total;
this.rows = rows;
}
//getter and setter .....
}
public PageResult findPage(int pageNum,int pageSize);
public PageResult findPage(int pageNum, int pageSize) {
// PageHelper为MyBatis分页插件
PageHelper.startPage(pageNum, pageSize);
Page<TbBrand> page=(Page<TbBrand>) brandMapper.selectByExample(null);
return new PageResult(page.getTotal(), page.getResult());
}
@RequestMapping("/findPage")
public PageResult findPage(int currentPage,int pageSize){
return brandService.findPage(currentPage, pageSize);
}
分页使用mybatis分页插件PageHelper
要记得将pojo和interface重新install下
分页前端
1.引入分页组件
<!-- 分页组件开始 -->
<script src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!-- 分页组件结束 -->
2.构建app模块时引入pagination模块
var app=angular.module('pinyougou',['pagination']);//定义品优购模块
3.页面的表格下放置分页组件
<!-- 分页 -->
<tm-pagination conf="paginationConf"></tm-pagination>
4.分页控件配置
//分页控件配置
$scope.paginationConf = {
currentPage: 1,
totalItems: 10,
itemsPerPage: 10,
perPageOptions: [10, 20, 30, 40, 50],
onChange: function(){
$scope.reloadList();//重新加载
}
完整的前面列表页面分页前端
<!-- 分页组件开始 -->
<script src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!-- 分页组件结束 -->
<script>
var app=angular.module("pinyougou",['pagination']); //定义品优购模块
app.controller("brandController",function($scope,$http){
$scope.findAll=function(){
$http.get("../brand/findAll.do").success(
function(response){
$scope.list=response;
});
}
$scope.reloadList=function(){
$scope.findPage($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
}
//分页控件配置
$scope.paginationConf = {
currentPage: 1,
totalItems: 10,
itemsPerPage: 10,
perPageOptions: [10, 20, 30, 40, 50],
onChange: function(){
//重新加载
$scope.reloadList();
}
};
//分页
$scope.findPage=function(page,rows){
$http.get("../brand/findPage.do?currentPage="+page+"&pageSize="+rows).success(
function(response){
$scope.list=response.rows; //当前页数据
$scope.paginationConf.totalItems=response.total; //总记录数
}
)
}
});
</script>
<tr ng-repeat="entity in list">
<td><input type="checkbox" ></td>
<td>{{entity.id}}</td>
<td>{{entity.name}}</td>
<td>{{entity.firstChar}}</td>
<td class="text-center">
<button type="button" class="btn bg-olive btn-xs" data-toggle="modal"
data-target="#editModal" >修改</button>
</td>
</tr>
<!--数据列表/-->
<!-- 分页 -->
<tm-pagination conf="paginationConf"></tm-pagination>
四:增加品牌
Controller层里面的实体类对象,需要用到@requestBody注解,并且告诉前端保存成功还是失败.
方法一:
{success:true,message:"保存成功"}
Map map=new HashMap();
map.put('success',true);
map.put('message',"保存成功");
方法二:
创建类:包含success 和 message
public interface BrandService {
public void save(TbBrand tbBrand);
}
@Service
public class BrandServiceImpl implements BrandService{
@Autowired
private TbBrandMapper brandMapper;
@Override
public void save(TbBrand tbBrand) {
brandMapper.insert(tbBrand);
}
}
//返回结果封装
public class Result implements Serializable{
private boolean success;
private String message;
public Result(boolean success, String message) {
super();
this.success = success;
this.message = message;
}
//getter and setter.....
}
public class BrandController {
@Reference
public BrandService brandService;
@RequestMapping("/add")
public Result save(@RequestBody TbBrand tbBrand){
try {
brandService.save(tbBrand);
return new Result(true, "添加成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "添加失败");
}
}
//新增
$scope.save=function(){
$http.post("../brand/add.do",$scope.entity).success(
function(response){
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
<tr>
<td>品牌名称</td>
<td><input class="form-control" placeholder="品牌名称" ng-model="entity.name" > </td>
</tr>
<tr>
<td>首字母</td>
<td><input class="form-control" placeholder="首字母" ng-model="entity.firstChar"> </td>
</tr>
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>
//为了每次打开窗口没有遗留上次的数据,我们可以修改新建按钮,对entity变量进行清空操作
<button type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ng-click="entity={}"> 新建</button>
五:修改品牌(保存和修改的时候,也可以在后端Controller里面判断是否有id,然后决定是添加还是修改)
//根据id查询品牌
public TbBrand findOne(Long id);
//修改品牌
public void update(TbBrand tbBrand);
public TbBrand findOne(Long id) {
return brandMapper.selectByPrimaryKey(id);
}
public void update(TbBrand tbBrand) {
brandMapper.updateByPrimaryKey(tbBrand);
}
@RequestMapping("/findOne")
public TbBrand findOne(Long id){
return brandService.findOne(id);
}
@RequestMapping("/update")
public Result update(@RequestBody TbBrand tbBrand){
try {
brandService.update(tbBrand);
return new Result(true,"修改成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(true,"修改失败");
}
}
//新增
$scope.save=function(){
var methodName='add';//方法名称
if($scope.entity.id !=null){//如果有ID
methodName='update'; //则执行修改方法
}
$http.post("../brand/"+methodName+".do",$scope.entity).success(
function(response){
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
//查询实体
$scope.findOne=function(id){
$http.get("../brand/findOne.do?id="+id).success(
function(response){
$scope.entity=response;
}
);
}
<button type="button" class="btn bg-olive btn-xs" data-toggle="modal"
data-target="#editModal" ng-click="findOne(entity.id)" >修改</button>
六:批量删除品牌
//批量删除品牌
public void deleteById(Long[] ids);
public void deleteById(Long[] ids) {
if(ids !=null && ids.length>0){
for (Long id : ids) {
brandMapper.deleteByPrimaryKey(id);
}
}
}
@RequestMapping("/delete")
public Result deleteById(Long[] ids){
try {
brandService.deleteById(ids);
return new Result(true,"删除成功");
} catch (Exception e) {
e.printStackTrace();
return new Result(false,"删除失败");
}
}
主要思路:我们需要定义一个用于存储选中ID的数组,当我们点击复选框后判断是选择还是取消选择,如果是选择就加到数组中,如果是取消选择就从数组中移除。在点击删除按钮时需要用到这个存储了ID的数组。
这里我们补充一下JS的关于数组操作的知识
(1) 数组的push方法:向数组中添加元素
(2) 数组的splice方法:从数组的指定位置移除指定个数的元素 ,参数1为位置 ,参数2位移除的个数
(3) 复选框的checked属性:用于判断是否被选中
$scope.selectIds=[];//选中的ID集合
//更新复选
$scope.updateSelection = function($event, id) {
if($event.target.checked){//如果是被选中,则增加到数组
$scope.selectIds.push( id);
}else{
var idx = $scope.selectIds.indexOf(id);
$scope.selectIds.splice(idx, 1);//删除
}
}
//批量删除
$scope.dele=function(){
//获取选中的复选框
$http.get('../brand/delete.do?ids='+$scope.selectIds).success(
function(response){
if(response.success){
$scope.reloadList();//刷新列表
}
}
);
}
//修改列表的复选框
<input type="checkbox" ng-click="updateSelection($event,entity.id)">
//修改删除按钮
<button type="button" class="btn btn-default" title="删除" ng-click="dele()"> 删除</button>
七:品牌条件查询
//品牌条件查询
public PageResult findPage(TbBrand tbBrand,int pageNum,int pageSize);
@Override
public PageResult findPage(TbBrand tbBrand, int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
TbBrandExample example=new TbBrandExample();
Criteria criteria = example.createCriteria();
if(tbBrand !=null){
if(tbBrand.getName() !=null && tbBrand.getName().length()>0){
criteria.andNameLike("%"+tbBrand.getName()+"%");
}
if(tbBrand.getFirstChar() !=null && tbBrand.getFirstChar().length()>0){
criteria.andFirstCharEqualTo(tbBrand.getFirstChar());
}
}
Page<TbBrand> page=(Page<TbBrand>) brandMapper.selectByExample(example);
return new PageResult(page.getTotal(), page.getResult());
}
@RequestMapping("/search")
public PageResult search(@RequestBody TbBrand tbBrand,int currentPage,int pageSize){
return brandService.findPage(tbBrand,currentPage, pageSize);
}
<div class="has-feedback">
品牌名称:<input ng-model="searchEntity.name"> 品牌首字母:<input ng-model="searchEntity.firstChar">
<button class="btn btn-default" ng-click="reloadList()">查询</button>
</div>
$scope.searchEntity={};//定义搜索对象
$scope.search=function(page,rows){
$http.post("../brand/search.do?currentPage="+page+"&pageSize="+rows,$scope.searchEntity).success(
function(response){
$scope.paginationConf.totalItems=response.total;//总记录数
$scope.list=response.rows;//当前页数据
}
);
}
/刷新列表
$scope.reloadList=function(){
$scope.search( $scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
}