①目标:
目标1:理解和运用angularJS的service(前端在分层的时候,前端的服务层。)
目标2:理解和运用控制器继承(控制器还可以继承。这个前端的思想,是从后端借鉴过来的。)
目标3:掌握一个代码生成器的使用(避免写过多重复的代码)
目标4:实现规格管理
目标5:实现模板管理
在做目标4和5的两个功能的时候,我们会涉及到一些比较复杂的控件。比如说:下拉列表控件(不是那种简单的文本框控件)。还有就是一对多的表的存储。比如说:我们要做的规格,涉及到两张表的存储。不是一个单一表的存储。
②前端分层开发
关于分层开发,大家一般来说都是在后端来进行分层开发。比如说我们这里后端分:数据访问层(dao层)、业务逻辑层(service层)、控制(controller)层、视图(view)层等等。我们在前端也可以进行分层。
之前的brand.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>品牌管理</title>
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
<link rel="stylesheet" href="../plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet" href="../css/style.css">
<script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="../plugins/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
<!-- 分页组件开始 -->
<script type="text/javascript" src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!-- 分页组件结束 -->
<script type="text/javascript">
var app = angular.module('pinyougou',['pagination']);//在js里可以用单引也可以用双引
app.directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
scope.$emit('ngRepeatFinished');
});
}
}
};
});
app.controller('brandController',function($scope,$http){
$scope.$on('ngRepeatFinished', function(){
//可执行DOM操作
for(var i=0;i< $scope.selectIds.length;i++){
for(var j=0;j<$scope.list.length;j++){
if( $scope.list[j].id == $scope.selectIds[i]){
//在渲染 完成后,对复选框的 显示进行更新,false表示不勾选,true表示勾选
document.getElementById(String($scope.list[j].id)).checked = $scope.boxes[$scope.list[j].id];
}
}}
});
//查询品牌列表数据
$scope.findAll = function(){
//之前的访问json的路径是http://localhost:9101/brand/findAll.do
//则现在,在brand.html文件../返回根目录,webapp根目录,再寻找/brand/findAll.do
$http.get('../brand/findAll.do').success(
function(response){
$scope.list = response;
}
);
}
$scope.paginationConf = {
//当前页
currentPage : 1,
//总记录数
totalItems : 10,
//每页记录数
itemsPerPage : 10,
//分页选项,下拉菜单
perPageOptions : [ 10, 20, 30, 40, 50 ],
//当页码重新变更后自动触发的方法
onChange : function() {
$scope.reloadList();
}};
//这个前端的方法名称findPage不一定要和后端的findPage方法名称一样,可以随意取
//只不过去一样的名称好辨别一些。
//分页
$scope.findPage = function(){
$scope.entity02 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage
};
$http.post('../brand/findPage.do',$scope.entity02).success(
function(response){
//显示当前一页的[{},{},...{}]内容
$scope.list = response.rows;
//更改更新总记录数,更改此变量值,前端分页控件
//自动获得值
$scope.paginationConf.totalItems = response.total;
}
);
}
$scope.reloadList = function(){
//$scope.findPage();
$scope.search();//否则又会还原成全部的数据呈现
}
//保存
$scope.save = function(){
var methodName = 'add';
if($scope.entity.id != null){
methodName = 'update';
}
$http.post('../brand/'+methodName+'.do',$scope.entity).success(
function(response){
if(response.success){
$scope.reloadList();//刷新
}else{
alert(response.message);
}
}
);
}
$scope.findOne = function($event){
$scope.entity03= {id: $event.target.parentNode.parentNode.children[1].innerText}
$http.post("../brand/findOne.do",$scope.entity03).success(
function(response){
$scope.entity = response;
}
);
}
$scope.selectIds = [];//用户勾选的ID集合
$scope.boxes = [];//保存复选框被选的状态,true(勾选)或者false(不勾选)
$scope.updateSelectIds = function($event,id){
if($event.target.checked){
$scope.selectIds.push(id);//push向集合添加元素
}else{
var index = $scope.selectIds.indexOf(id);//查找id值在集合中的位置
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
$scope.saveStatus();
}
//保存CheckBox复选框的true和false的状态
$scope.saveStatus = function(){
for(var j=0;j<$scope.list.length;j++){
for(var i=0;i< $scope.selectIds.length;i++){
//从第0位查找id为$scope.list[j].id的值,是否有这个id在$scope.selectIds里
if($scope.selectIds.indexOf($scope.list[j].id,0)!=-1){
$scope.boxes[$scope.list[j].id] = true;
}else{
$scope.boxes[$scope.list[j].id]= false;
}
}
}
}
$scope.dele = function(){
$scope.entity04=[];
for(var i=0;i<$scope.selectIds.length;i++){
$scope.entity04.push({id: $scope.selectIds[i]}) ;
}
$http.post("../brand/delete.do",$scope.entity04).success(
function(response){
for(var i=0;i<$scope.selectIds.length;i++){
//查找id值在集合中的位置
var index = $scope.selectIds.indexOf($scope.selectIds[i]);
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
$scope.searchEntity = {};
//条件查询
$scope.search = function(){
$scope.entity05 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage,
brand: $scope.searchEntity
};
$http.post("../brand/search.do",$scope.entity05).success(
function(response) {
$scope.list = response.rows;
$scope.paginationConf.totalItems = response.total;
}
)
}
});
</script>
</head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" >
<!-- .box-body -->
<div class="box-header with-border">
<h3 class="box-title">品牌管理</h3>
</div>
<div class="box-body">
<!-- 数据表格 -->
<div class="table-box">
<!--工具栏-->
<div class="pull-left">
<div class="form-group form-inline">
<div class="btn-group">
<button type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ng-click="entity={}" ><i class="fa fa-file-o"></i> 新建</button>
<button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o"></i> 删除</button>
<button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"><i class="fa fa-refresh"></i> 刷新</button>
</div>
</div>
</div>
<div class="box-tools pull-right">
<div class="has-feedback">
品牌名称:<input ng-model="searchEntity.name"> 品牌首字母:<input ng-model="searchEntity.firstChar"> <button class="btn btn-default" ng-click="search()">查询</button>
</div>
</div>
<!--工具栏/-->
<!--数据列表-->
<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="text-center">操作</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="entity in list" on-finish-render-filters>
<td><input type="checkbox" id="{{entity.id}}"
ng-click="updateSelectIds($event,entity.id)" /></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" ng-click="findOne($event)">修改</button>
</td>
</tr>
</tbody>
</table>
<!--数据列表/-->
</div>
<!-- 数据表格 /-->
<tm-pagination conf="paginationConf" ></tm-pagination>
</div>
<!-- /.box-body -->
<!-- 编辑窗口 -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" >
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">品牌编辑</h3>
</div>
<div class="modal-body">
<table class="table table-bordered table-striped" width="800px">
<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>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭</button>
</div>
</div>
</div>
</div>
</body>
</html>
我们现在其实是不分层的。代码和页面的内容都融在了一块。
还有很多和后端交互的代码,如:
$http.post('../brand/findPage.do',$scope.entity02).success。。。。。
这种和后端交互的代码,其实是属于一种服务(service层)即属于一种逻辑。
这样混在一起,不利于后期的维护。angularJS可以自定义自己的服务(service)。
例如:品牌的findAll方法,$http.get('../brand/findAll.do').success(。。。。。。在当前这个控制器可能使用,在别的控制器,另外的地方,也可能使用这个地址。那在另外的控制器,还要把这个再写一遍。但是如果说,findAll这个方法的地址发生变更了,或者参数改了,等等。因为这个业务逻辑是一样的,所以每个控制器都要去更改,如果很多,这种更改将是灾难性的。所以,应该把这一部分抽离出来,单独建成一个服务。说到服务,我们接触过,如$http,这个东西就是服务,只不过是angularJS的内置服务。封装了一系列的方法。我们自己也可以自定义服务。
③写出前端服务(service)层
同样的方法可以把其他几个服务都写了。
brand.html的服务层内容为:
//app为模块对象,控制器有控制器的名字,服务也要有服务的名字。
//和控制器一样也是有function并且可以接受参数和内容。
//品牌服务
app.service("brandService",function($http){
//不能用$scope,要用this,这是他本身。
this.findAll = function(){
//.success后面的内容,$scope.list = response;给了视图
//与视图交互,又与后端交互
//.success后面的内容是控制层的内容。
//所以只写前面的内容$http.get('../brand/findAll.do');
return $http.get('../brand/findAll.do');
}
this.findPage = function(entity08){
return $http.post('../brand/findPage.do',entity08);
}
this.findOne = function(entity09){
return $http.post("../brand/findOne.do",entity09);
}
this.add = function(entity06){
return $http.post('../brand/add.do', entity06);
}
this.update = function(entity07){
return $http.post('../brand/update.do', entity07);
}
this.dele = function(entity10){
return $http.post('../brand/delete.do',entity10);
}
this.search = function(entity11){
return $http.post("../brand/search.do",entity11);
}
});
brand.html的控制层内容为:
app.controller('brandController',function($scope,$http,brandService){
$scope.$on('ngRepeatFinished', function(){
//可执行DOM操作
for(var i=0;i< $scope.selectIds.length;i++){
for(var j=0;j<$scope.list.length;j++){
if( $scope.list[j].id == $scope.selectIds[i]){
//在渲染 完成后,对复选框的 显示进行更新,false表示不勾选,true表示勾选
document.getElementById(String($scope.list[j].id)).checked = $scope.boxes[$scope.list[j].id];
}
}}
});
//查询品牌列表数据
$scope.findAll = function(){
//之前的访问json的路径是http://localhost:9101/brand/findAll.do
//则现在,在brand.html文件../返回根目录,webapp根目录,再寻找/brand/findAll.do
brandService.findAll().success(
function(response){
$scope.list = response;
}
);
}
$scope.paginationConf = {
//当前页
currentPage : 1,
//总记录数
totalItems : 10,
//每页记录数
itemsPerPage : 10,
//分页选项,下拉菜单
perPageOptions : [ 10, 20, 30, 40, 50 ],
//当页码重新变更后自动触发的方法
onChange : function() {
$scope.reloadList();
}};
//这个前端的方法名称findPage不一定要和后端的findPage方法名称一样,可以随意取
//只不过去一样的名称好辨别一些。
//分页
$scope.findPage = function(){
$scope.entity02 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage
};
brandService.findPage($scope.entity02).success(
function(response){
//显示当前一页的[{},{},...{}]内容
$scope.list = response.rows;
//更改更新总记录数,更改此变量值,前端分页控件
//自动获得值
$scope.paginationConf.totalItems = response.total;
}
);
}
$scope.reloadList = function(){
//$scope.findPage();
$scope.search();//否则又会还原成全部的数据呈现
}
//保存
$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(response){
if(response.success){
$scope.reloadList();//刷新
}else{
alert(response.message);
}
}
);
}
$scope.findOne = function($event){
$scope.entity03= {id: $event.target.parentNode.parentNode.children[1].innerText}
brandService.findOne($scope.entity03).success(
function(response){
$scope.entity = response;
}
);
}
$scope.selectIds = [];//用户勾选的ID集合
$scope.boxes = [];//保存复选框被选的状态,true(勾选)或者false(不勾选)
$scope.updateSelectIds = function($event,id){
if($event.target.checked){
$scope.selectIds.push(id);//push向集合添加元素
}else{
var index = $scope.selectIds.indexOf(id);//查找id值在集合中的位置
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
$scope.saveStatus();
}
//保存CheckBox复选框的true和false的状态
$scope.saveStatus = function(){
for(var j=0;j<$scope.list.length;j++){
for(var i=0;i< $scope.selectIds.length;i++){
//从第0位查找id为$scope.list[j].id的值,是否有这个id在$scope.selectIds里
if($scope.selectIds.indexOf($scope.list[j].id,0)!=-1){
$scope.boxes[$scope.list[j].id] = true;
}else{
$scope.boxes[$scope.list[j].id]= false;
}
}
}
}
$scope.dele = function(){
$scope.entity04=[];
for(var i=0;i<$scope.selectIds.length;i++){
$scope.entity04.push({id: $scope.selectIds[i]}) ;
}
brandService.dele($scope.entity04).success(
function(response){
for(var i=0;i<$scope.selectIds.length;i++){
//查找id值在集合中的位置
var index = $scope.selectIds.indexOf($scope.selectIds[i]);
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
$scope.searchEntity = {};
//条件查询
$scope.search = function(){
$scope.entity05 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage,
brand: $scope.searchEntity
};
brandService.search($scope.entity05).success(
function(response) {
$scope.list = response.rows;
$scope.paginationConf.totalItems = response.total;
}
)
}
});
brand.html文件的目前的内容为:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>品牌管理</title>
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
<link rel="stylesheet" href="../plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet" href="../css/style.css">
<script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="../plugins/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
<!-- 分页组件开始 -->
<script type="text/javascript" src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!-- 分页组件结束 -->
<script type="text/javascript">
var app = angular.module('pinyougou',['pagination']);//在js里可以用单引也可以用双引
app.directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
scope.$emit('ngRepeatFinished');
});
}
}
};
});
//app为模块对象,控制器有控制器的名字,服务也要有服务的名字。
//和控制器一样也是有function并且可以接受参数和内容。
//品牌服务
app.service("brandService",function($http){
//不能用$scope,要用this,这是他本身。
this.findAll = function(){
//.success后面的内容,$scope.list = response;给了视图
//与视图交互,又与后端交互
//.success后面的内容是控制层的内容。
//所以只写前面的内容$http.get('../brand/findAll.do');
return $http.get('../brand/findAll.do');
}
this.findPage = function(entity08){
return $http.post('../brand/findPage.do',entity08);
}
this.findOne = function(entity09){
return $http.post("../brand/findOne.do",entity09);
}
this.add = function(entity06){
return $http.post('../brand/add.do', entity06);
}
this.update = function(entity07){
return $http.post('../brand/update.do', entity07);
}
this.dele = function(entity10){
return $http.post('../brand/delete.do',entity10);
}
this.search = function(entity11){
return $http.post("../brand/search.do",entity11);
}
});
app.controller('brandController',function($scope,$http,brandService){
$scope.$on('ngRepeatFinished', function(){
//可执行DOM操作
for(var i=0;i< $scope.selectIds.length;i++){
for(var j=0;j<$scope.list.length;j++){
if( $scope.list[j].id == $scope.selectIds[i]){
//在渲染 完成后,对复选框的 显示进行更新,false表示不勾选,true表示勾选
document.getElementById(String($scope.list[j].id)).checked = $scope.boxes[$scope.list[j].id];
}
}}
});
//查询品牌列表数据
$scope.findAll = function(){
//之前的访问json的路径是http://localhost:9101/brand/findAll.do
//则现在,在brand.html文件../返回根目录,webapp根目录,再寻找/brand/findAll.do
brandService.findAll().success(
function(response){
$scope.list = response;
}
);
}
$scope.paginationConf = {
//当前页
currentPage : 1,
//总记录数
totalItems : 10,
//每页记录数
itemsPerPage : 10,
//分页选项,下拉菜单
perPageOptions : [ 10, 20, 30, 40, 50 ],
//当页码重新变更后自动触发的方法
onChange : function() {
$scope.reloadList();
}};
//这个前端的方法名称findPage不一定要和后端的findPage方法名称一样,可以随意取
//只不过去一样的名称好辨别一些。
//分页
$scope.findPage = function(){
$scope.entity02 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage
};
brandService.findPage($scope.entity02).success(
function(response){
//显示当前一页的[{},{},...{}]内容
$scope.list = response.rows;
//更改更新总记录数,更改此变量值,前端分页控件
//自动获得值
$scope.paginationConf.totalItems = response.total;
}
);
}
$scope.reloadList = function(){
//$scope.findPage();
$scope.search();//否则又会还原成全部的数据呈现
}
//保存
$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(response){
if(response.success){
$scope.reloadList();//刷新
}else{
alert(response.message);
}
}
);
}
$scope.findOne = function($event){
$scope.entity03= {id: $event.target.parentNode.parentNode.children[1].innerText}
brandService.findOne($scope.entity03).success(
function(response){
$scope.entity = response;
}
);
}
$scope.selectIds = [];//用户勾选的ID集合
$scope.boxes = [];//保存复选框被选的状态,true(勾选)或者false(不勾选)
$scope.updateSelectIds = function($event,id){
if($event.target.checked){
$scope.selectIds.push(id);//push向集合添加元素
}else{
var index = $scope.selectIds.indexOf(id);//查找id值在集合中的位置
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
$scope.saveStatus();
}
//保存CheckBox复选框的true和false的状态
$scope.saveStatus = function(){
for(var j=0;j<$scope.list.length;j++){
for(var i=0;i< $scope.selectIds.length;i++){
//从第0位查找id为$scope.list[j].id的值,是否有这个id在$scope.selectIds里
if($scope.selectIds.indexOf($scope.list[j].id,0)!=-1){
$scope.boxes[$scope.list[j].id] = true;
}else{
$scope.boxes[$scope.list[j].id]= false;
}
}
}
}
$scope.dele = function(){
$scope.entity04=[];
for(var i=0;i<$scope.selectIds.length;i++){
$scope.entity04.push({id: $scope.selectIds[i]}) ;
}
brandService.dele($scope.entity04).success(
function(response){
for(var i=0;i<$scope.selectIds.length;i++){
//查找id值在集合中的位置
var index = $scope.selectIds.indexOf($scope.selectIds[i]);
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
$scope.searchEntity = {};
//条件查询
$scope.search = function(){
$scope.entity05 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage,
brand: $scope.searchEntity
};
brandService.search($scope.entity05).success(
function(response) {
$scope.list = response.rows;
$scope.paginationConf.totalItems = response.total;
}
)
}
});
</script>
</head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" >
<!-- .box-body -->
<div class="box-header with-border">
<h3 class="box-title">品牌管理</h3>
</div>
<div class="box-body">
<!-- 数据表格 -->
<div class="table-box">
<!--工具栏-->
<div class="pull-left">
<div class="form-group form-inline">
<div class="btn-group">
<button type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ng-click="entity={}" ><i class="fa fa-file-o"></i> 新建</button>
<button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o"></i> 删除</button>
<button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"><i class="fa fa-refresh"></i> 刷新</button>
</div>
</div>
</div>
<div class="box-tools pull-right">
<div class="has-feedback">
品牌名称:<input ng-model="searchEntity.name"> 品牌首字母:<input ng-model="searchEntity.firstChar"> <button class="btn btn-default" ng-click="search()">查询</button>
</div>
</div>
<!--工具栏/-->
<!--数据列表-->
<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="text-center">操作</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="entity in list" on-finish-render-filters>
<td><input type="checkbox" id="{{entity.id}}"
ng-click="updateSelectIds($event,entity.id)" /></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" ng-click="findOne($event)">修改</button>
</td>
</tr>
</tbody>
</table>
<!--数据列表/-->
</div>
<!-- 数据表格 /-->
<tm-pagination conf="paginationConf" ></tm-pagination>
</div>
<!-- /.box-body -->
<!-- 编辑窗口 -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" >
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">品牌编辑</h3>
</div>
<div class="modal-body">
<table class="table table-bordered table-striped" width="800px">
<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>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭</button>
</div>
</div>
</div>
</div>
</body>
</html>
④代码分离JS
一、base.js文件
var app = angular.module('pinyougou',[]);//在js里可以用单引也可以用双引,定义品优购模块
二、base_pagination.js文件
var app = angular.module('pinyougou',['pagination']);//在js里可以用单引也可以用双引
三、service文件夹,单独放前端service层的东西
四、brandService.js文件
//app为模块对象,控制器有控制器的名字,服务也要有服务的名字。
//和控制器一样也是有function并且可以接受参数和内容。
//品牌服务
app.service("brandService",function($http){
//不能用$scope,要用this,这是他本身。
this.findAll = function(){
//.success后面的内容,$scope.list = response;给了视图
//与视图交互,又与后端交互
//.success后面的内容是控制层的内容。
//所以只写前面的内容$http.get('../brand/findAll.do');
return $http.get('../brand/findAll.do');
}
this.findPage = function(entity08){
return $http.post('../brand/findPage.do',entity08);
}
this.findOne = function(entity09){
return $http.post("../brand/findOne.do",entity09);
}
this.add = function(entity06){
return $http.post('../brand/add.do', entity06);
}
this.update = function(entity07){
return $http.post('../brand/update.do', entity07);
}
this.dele = function(entity10){
return $http.post('../brand/delete.do',entity10);
}
this.search = function(entity11){
return $http.post("../brand/search.do",entity11);
}
});
五、controller文件夹,单独放前端controller层的东西。
六、brandController.js文件
app.controller('brandController',function($scope,$http,brandService){
$scope.$on('ngRepeatFinished', function(){
//可执行DOM操作
for(var i=0;i< $scope.selectIds.length;i++){
for(var j=0;j<$scope.list.length;j++){
if( $scope.list[j].id == $scope.selectIds[i]){
//在渲染 完成后,对复选框的 显示进行更新,false表示不勾选,true表示勾选
document.getElementById(String($scope.list[j].id)).checked = $scope.boxes[$scope.list[j].id];
}
}}
});
//查询品牌列表数据
$scope.findAll = function(){
//之前的访问json的路径是http://localhost:9101/brand/findAll.do
//则现在,在brand.html文件../返回根目录,webapp根目录,再寻找/brand/findAll.do
brandService.findAll().success(
function(response){
$scope.list = response;
}
);
}
$scope.paginationConf = {
//当前页
currentPage : 1,
//总记录数
totalItems : 10,
//每页记录数
itemsPerPage : 10,
//分页选项,下拉菜单
perPageOptions : [ 10, 20, 30, 40, 50 ],
//当页码重新变更后自动触发的方法
onChange : function() {
$scope.reloadList();
}};
//这个前端的方法名称findPage不一定要和后端的findPage方法名称一样,可以随意取
//只不过去一样的名称好辨别一些。
//分页
$scope.findPage = function(){
$scope.entity02 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage
};
brandService.findPage($scope.entity02).success(
function(response){
//显示当前一页的[{},{},...{}]内容
$scope.list = response.rows;
//更改更新总记录数,更改此变量值,前端分页控件
//自动获得值
$scope.paginationConf.totalItems = response.total;
}
);
}
$scope.reloadList = function(){
//$scope.findPage();
$scope.search();//否则又会还原成全部的数据呈现
}
//保存
$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(response){
if(response.success){
$scope.reloadList();//刷新
}else{
alert(response.message);
}
}
);
}
$scope.findOne = function($event){
$scope.entity03= {id: $event.target.parentNode.parentNode.children[1].innerText}
brandService.findOne($scope.entity03).success(
function(response){
$scope.entity = response;
}
);
}
$scope.selectIds = [];//用户勾选的ID集合
$scope.boxes = [];//保存复选框被选的状态,true(勾选)或者false(不勾选)
$scope.updateSelectIds = function($event,id){
if($event.target.checked){
$scope.selectIds.push(id);//push向集合添加元素
}else{
var index = $scope.selectIds.indexOf(id);//查找id值在集合中的位置
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
$scope.saveStatus();
}
//保存CheckBox复选框的true和false的状态
$scope.saveStatus = function(){
for(var j=0;j<$scope.list.length;j++){
for(var i=0;i< $scope.selectIds.length;i++){
//从第0位查找id为$scope.list[j].id的值,是否有这个id在$scope.selectIds里
if($scope.selectIds.indexOf($scope.list[j].id,0)!=-1){
$scope.boxes[$scope.list[j].id] = true;
}else{
$scope.boxes[$scope.list[j].id]= false;
}
}
}
}
$scope.dele = function(){
$scope.entity04=[];
for(var i=0;i<$scope.selectIds.length;i++){
$scope.entity04.push({id: $scope.selectIds[i]}) ;
}
brandService.dele($scope.entity04).success(
function(response){
for(var i=0;i<$scope.selectIds.length;i++){
//查找id值在集合中的位置
var index = $scope.selectIds.indexOf($scope.selectIds[i]);
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
$scope.searchEntity = {};
//条件查询
$scope.search = function(){
$scope.entity05 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage,
brand: $scope.searchEntity
};
brandService.search($scope.entity05).success(
function(response) {
$scope.list = response.rows;
$scope.paginationConf.totalItems = response.total;
}
)
}
});
七、render_finish.js文件(渲染完成)
app.directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
scope.$emit('ngRepeatFinished');
});
}
}
};
});
八、brand.html文件更改
删除以下内容:
<!-- 删除以下内容
<script type="text/javascript">
var app = angular.module('pinyougou',['pagination']);//在js里可以用单引也可以用双引
app.directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
scope.$emit('ngRepeatFinished');
});
}
}
};
});
//app为模块对象,控制器有控制器的名字,服务也要有服务的名字。
//和控制器一样也是有function并且可以接受参数和内容。
//品牌服务
app.service("brandService",function($http){
//不能用$scope,要用this,这是他本身。
this.findAll = function(){
//.success后面的内容,$scope.list = response;给了视图
//与视图交互,又与后端交互
//.success后面的内容是控制层的内容。
//所以只写前面的内容$http.get('../brand/findAll.do');
return $http.get('../brand/findAll.do');
}
this.findPage = function(entity08){
return $http.post('../brand/findPage.do',entity08);
}
this.findOne = function(entity09){
return $http.post("../brand/findOne.do",entity09);
}
this.add = function(entity06){
return $http.post('../brand/add.do', entity06);
}
this.update = function(entity07){
return $http.post('../brand/update.do', entity07);
}
this.dele = function(entity10){
return $http.post('../brand/delete.do',entity10);
}
this.search = function(entity11){
return $http.post("../brand/search.do",entity11);
}
});
app.controller('brandController',function($scope,$http,brandService){
$scope.$on('ngRepeatFinished', function(){
//可执行DOM操作
for(var i=0;i< $scope.selectIds.length;i++){
for(var j=0;j<$scope.list.length;j++){
if( $scope.list[j].id == $scope.selectIds[i]){
//在渲染 完成后,对复选框的 显示进行更新,false表示不勾选,true表示勾选
document.getElementById(String($scope.list[j].id)).checked = $scope.boxes[$scope.list[j].id];
}
}}
});
//查询品牌列表数据
$scope.findAll = function(){
//之前的访问json的路径是http://localhost:9101/brand/findAll.do
//则现在,在brand.html文件../返回根目录,webapp根目录,再寻找/brand/findAll.do
brandService.findAll().success(
function(response){
$scope.list = response;
}
);
}
$scope.paginationConf = {
//当前页
currentPage : 1,
//总记录数
totalItems : 10,
//每页记录数
itemsPerPage : 10,
//分页选项,下拉菜单
perPageOptions : [ 10, 20, 30, 40, 50 ],
//当页码重新变更后自动触发的方法
onChange : function() {
$scope.reloadList();
}};
//这个前端的方法名称findPage不一定要和后端的findPage方法名称一样,可以随意取
//只不过去一样的名称好辨别一些。
//分页
$scope.findPage = function(){
$scope.entity02 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage
};
brandService.findPage($scope.entity02).success(
function(response){
//显示当前一页的[{},{},...{}]内容
$scope.list = response.rows;
//更改更新总记录数,更改此变量值,前端分页控件
//自动获得值
$scope.paginationConf.totalItems = response.total;
}
);
}
$scope.reloadList = function(){
//$scope.findPage();
$scope.search();//否则又会还原成全部的数据呈现
}
//保存
$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(response){
if(response.success){
$scope.reloadList();//刷新
}else{
alert(response.message);
}
}
);
}
$scope.findOne = function($event){
$scope.entity03= {id: $event.target.parentNode.parentNode.children[1].innerText}
brandService.findOne($scope.entity03).success(
function(response){
$scope.entity = response;
}
);
}
$scope.selectIds = [];//用户勾选的ID集合
$scope.boxes = [];//保存复选框被选的状态,true(勾选)或者false(不勾选)
$scope.updateSelectIds = function($event,id){
if($event.target.checked){
$scope.selectIds.push(id);//push向集合添加元素
}else{
var index = $scope.selectIds.indexOf(id);//查找id值在集合中的位置
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
$scope.saveStatus();
}
//保存CheckBox复选框的true和false的状态
$scope.saveStatus = function(){
for(var j=0;j<$scope.list.length;j++){
for(var i=0;i< $scope.selectIds.length;i++){
//从第0位查找id为$scope.list[j].id的值,是否有这个id在$scope.selectIds里
if($scope.selectIds.indexOf($scope.list[j].id,0)!=-1){
$scope.boxes[$scope.list[j].id] = true;
}else{
$scope.boxes[$scope.list[j].id]= false;
}
}
}
}
$scope.dele = function(){
$scope.entity04=[];
for(var i=0;i<$scope.selectIds.length;i++){
$scope.entity04.push({id: $scope.selectIds[i]}) ;
}
brandService.dele($scope.entity04).success(
function(response){
for(var i=0;i<$scope.selectIds.length;i++){
//查找id值在集合中的位置
var index = $scope.selectIds.indexOf($scope.selectIds[i]);
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
$scope.searchEntity = {};
//条件查询
$scope.search = function(){
$scope.entity05 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage,
brand: $scope.searchEntity
};
brandService.search($scope.entity05).success(
function(response) {
$scope.list = response.rows;
$scope.paginationConf.totalItems = response.total;
}
)
}
});
</script>
-->
然后引入上面写的js代码文件
现在brand.html文件的代码为:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>品牌管理</title>
<meta content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" name="viewport">
<link rel="stylesheet" href="../plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/AdminLTE.css">
<link rel="stylesheet" href="../plugins/adminLTE/css/skins/_all-skins.min.css">
<link rel="stylesheet" href="../css/style.css">
<script src="../plugins/jQuery/jquery-2.2.3.min.js"></script>
<script src="../plugins/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../plugins/angularjs/angular.min.js"></script>
<!-- 分页组件开始 -->
<script type="text/javascript" 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/render_finish.js"></script>
<script type="text/javascript" src="../js/service/brandService.js"></script>
<script type="text/javascript" src="../js/controller/brandController.js"></script>
<!-- 删除以下内容
<script type="text/javascript">
var app = angular.module('pinyougou',['pagination']);//在js里可以用单引也可以用双引
app.directive('onFinishRenderFilters', function ($timeout) {
return {
restrict: 'A',
link: function(scope, element, attr) {
if (scope.$last === true) {
$timeout(function() {
scope.$emit('ngRepeatFinished');
});
}
}
};
});
//app为模块对象,控制器有控制器的名字,服务也要有服务的名字。
//和控制器一样也是有function并且可以接受参数和内容。
//品牌服务
app.service("brandService",function($http){
//不能用$scope,要用this,这是他本身。
this.findAll = function(){
//.success后面的内容,$scope.list = response;给了视图
//与视图交互,又与后端交互
//.success后面的内容是控制层的内容。
//所以只写前面的内容$http.get('../brand/findAll.do');
return $http.get('../brand/findAll.do');
}
this.findPage = function(entity08){
return $http.post('../brand/findPage.do',entity08);
}
this.findOne = function(entity09){
return $http.post("../brand/findOne.do",entity09);
}
this.add = function(entity06){
return $http.post('../brand/add.do', entity06);
}
this.update = function(entity07){
return $http.post('../brand/update.do', entity07);
}
this.dele = function(entity10){
return $http.post('../brand/delete.do',entity10);
}
this.search = function(entity11){
return $http.post("../brand/search.do",entity11);
}
});
app.controller('brandController',function($scope,$http,brandService){
$scope.$on('ngRepeatFinished', function(){
//可执行DOM操作
for(var i=0;i< $scope.selectIds.length;i++){
for(var j=0;j<$scope.list.length;j++){
if( $scope.list[j].id == $scope.selectIds[i]){
//在渲染 完成后,对复选框的 显示进行更新,false表示不勾选,true表示勾选
document.getElementById(String($scope.list[j].id)).checked = $scope.boxes[$scope.list[j].id];
}
}}
});
//查询品牌列表数据
$scope.findAll = function(){
//之前的访问json的路径是http://localhost:9101/brand/findAll.do
//则现在,在brand.html文件../返回根目录,webapp根目录,再寻找/brand/findAll.do
brandService.findAll().success(
function(response){
$scope.list = response;
}
);
}
$scope.paginationConf = {
//当前页
currentPage : 1,
//总记录数
totalItems : 10,
//每页记录数
itemsPerPage : 10,
//分页选项,下拉菜单
perPageOptions : [ 10, 20, 30, 40, 50 ],
//当页码重新变更后自动触发的方法
onChange : function() {
$scope.reloadList();
}};
//这个前端的方法名称findPage不一定要和后端的findPage方法名称一样,可以随意取
//只不过去一样的名称好辨别一些。
//分页
$scope.findPage = function(){
$scope.entity02 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage
};
brandService.findPage($scope.entity02).success(
function(response){
//显示当前一页的[{},{},...{}]内容
$scope.list = response.rows;
//更改更新总记录数,更改此变量值,前端分页控件
//自动获得值
$scope.paginationConf.totalItems = response.total;
}
);
}
$scope.reloadList = function(){
//$scope.findPage();
$scope.search();//否则又会还原成全部的数据呈现
}
//保存
$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(response){
if(response.success){
$scope.reloadList();//刷新
}else{
alert(response.message);
}
}
);
}
$scope.findOne = function($event){
$scope.entity03= {id: $event.target.parentNode.parentNode.children[1].innerText}
brandService.findOne($scope.entity03).success(
function(response){
$scope.entity = response;
}
);
}
$scope.selectIds = [];//用户勾选的ID集合
$scope.boxes = [];//保存复选框被选的状态,true(勾选)或者false(不勾选)
$scope.updateSelectIds = function($event,id){
if($event.target.checked){
$scope.selectIds.push(id);//push向集合添加元素
}else{
var index = $scope.selectIds.indexOf(id);//查找id值在集合中的位置
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
$scope.saveStatus();
}
//保存CheckBox复选框的true和false的状态
$scope.saveStatus = function(){
for(var j=0;j<$scope.list.length;j++){
for(var i=0;i< $scope.selectIds.length;i++){
//从第0位查找id为$scope.list[j].id的值,是否有这个id在$scope.selectIds里
if($scope.selectIds.indexOf($scope.list[j].id,0)!=-1){
$scope.boxes[$scope.list[j].id] = true;
}else{
$scope.boxes[$scope.list[j].id]= false;
}
}
}
}
$scope.dele = function(){
$scope.entity04=[];
for(var i=0;i<$scope.selectIds.length;i++){
$scope.entity04.push({id: $scope.selectIds[i]}) ;
}
brandService.dele($scope.entity04).success(
function(response){
for(var i=0;i<$scope.selectIds.length;i++){
//查找id值在集合中的位置
var index = $scope.selectIds.indexOf($scope.selectIds[i]);
if(index != -1){
$scope.selectIds.splice(index,1);//从某个位置移掉几个元素
}
}
if(response.success){
$scope.reloadList();
}else{
alert(response.message);
}
}
);
}
$scope.searchEntity = {};
//条件查询
$scope.search = function(){
$scope.entity05 = {
pageNum: $scope.paginationConf.currentPage,
sizeNum: $scope.paginationConf.itemsPerPage,
brand: $scope.searchEntity
};
brandService.search($scope.entity05).success(
function(response) {
$scope.list = response.rows;
$scope.paginationConf.totalItems = response.total;
}
)
}
});
</script>
-->
</head>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" >
<!-- .box-body -->
<div class="box-header with-border">
<h3 class="box-title">品牌管理</h3>
</div>
<div class="box-body">
<!-- 数据表格 -->
<div class="table-box">
<!--工具栏-->
<div class="pull-left">
<div class="form-group form-inline">
<div class="btn-group">
<button type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ng-click="entity={}" ><i class="fa fa-file-o"></i> 新建</button>
<button type="button" class="btn btn-default" title="删除" ng-click="dele()"><i class="fa fa-trash-o"></i> 删除</button>
<button type="button" class="btn btn-default" title="刷新" onclick="window.location.reload();"><i class="fa fa-refresh"></i> 刷新</button>
</div>
</div>
</div>
<div class="box-tools pull-right">
<div class="has-feedback">
品牌名称:<input ng-model="searchEntity.name"> 品牌首字母:<input ng-model="searchEntity.firstChar"> <button class="btn btn-default" ng-click="search()">查询</button>
</div>
</div>
<!--工具栏/-->
<!--数据列表-->
<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="text-center">操作</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="entity in list" on-finish-render-filters>
<td><input type="checkbox" id="{{entity.id}}"
ng-click="updateSelectIds($event,entity.id)" /></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" ng-click="findOne($event)">修改</button>
</td>
</tr>
</tbody>
</table>
<!--数据列表/-->
</div>
<!-- 数据表格 /-->
<tm-pagination conf="paginationConf" ></tm-pagination>
</div>
<!-- /.box-body -->
<!-- 编辑窗口 -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" >
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="myModalLabel">品牌编辑</h3>
</div>
<div class="modal-body">
<table class="table table-bordered table-striped" width="800px">
<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>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>
<button class="btn btn-default" data-dismiss="modal" aria-hidden="true">关闭</button>
</div>
</div>
</div>
</div>
</body>
</html>