dubbo 购物平台搭建笔记(二)后端项目搭建和运行、angularJs前端项目搭建 [伪继承]

第一部分:angularJs前端项目搭建

前端搭建 angular.js

angularjs的特征

     特征一:mvc模式

Model:数据,其实就是angular变量($scope.XX);

View: 数据的呈现,Html+Directive(指令);

Controller:操作数据,就是function,数据的增删改查;

  特征二:双向绑定

框架采用并扩展了传统HTML,通过双向的数据绑定来适应动态内容,双向的数据绑定允许模型和视图之间的自动同步

特征三:依赖注入

依赖注入(Dependency Injection,简称DI)是一种设计模式, 指某个对象依赖的其他对象无需手工创建

特征四:模块化设计

高内聚低耦合法则

  1)官方提供的模块        ng、ngRoute、ngAnimate

   2)用户自定义的模块     angular.module('模块名',[ ])

 

 

当网页加载完毕,AngularJS 自动开启。

ng-app 指令告诉 AngularJS,<div> 元素是 AngularJS 应用程序 的"所有者"。

ng-model 指令把输入域的值绑定到应用程序变量 name

ng-bind 指令把应用程序变量 name 绑定到某个段落的 innerHTML。

ng-init 初始化

第二部分 angular入门:

 a.ng-app声明容器

<html>
<head>
<title>angularJs入門</title>
<script src="angular.min.js"></script>
</head>
<body ng-app>
	{{100+100}}
</body>
</html>

b.双向绑定

<html>
<head>
<title>angularJs入門</title>
<script src="angular.min.js"></script>
</head>
<body ng-app>
	请输入您的姓名:<input ng-model="name">
	{{name}}
</body>
</html>

c.初始化变量值

<html>
<head>
<title>angularJs入門 初始化</title>
<script src="angular.min.js"></script>
</head>
<body ng-app ng-init="name='朱世明'">
	请输入您的姓名:
	<input ng-model="name">
	<input ng-model="name">
	{{name}}
</body>
</html>

d.事件指令 ng-click -- 指定$scope.z在计算后显示出来

<html>
<head>
<title>angularJs入門 事件指令</title>
<script src="angular.min.js"></script>
<script>
  
    //  建立模块 
	var myapp = angular.module("myApp",[]);
	
	//  创建控制器  $scope相当于public
	myapp.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>

e.数组循环  ng-repeat  $scope.list

<html>
<head>
<title>angularJs入門 循环数组</title>
<script src="angular.min.js"></script>
<script>
  
    //  建立模块 
	var myapp = angular.module("myApp",[]);
	
	//  创建控制器  $scope相当于public
	myapp.controller("myController",function($scope){
		
		$scope.list = [110,221,331,2221,666];	
			
	});
</script>
</head>
<body ng-app="myApp" ng-controller="myController">
	<table>
	   <tr ng-repeat="x in list">
			<td>{{x}}</td>
	   </tr>
	</table>
</body>
</html>

f.循环对象数组 

<html>
<head>
<title>angularJs入門 循环对象数组</title>
<script src="angular.min.js"></script>
<script>
  
    //  建立模块 
	var myapp = angular.module("myApp",[]);
	
	//  创建控制器  $scope相当于public
	myapp.controller("myController",function($scope){
		
		$scope.list = [
			{name:'张三',age:10,score:100,subjectname:'语文'},
			{name:'李四',age:11,score:101,subjectname:'语文1'},
			{name:'王五',age:12,score:102,subjectname:'语文2'},
			{name:'赵柳',age:13,score:103,subjectname:'语文3'}
		];	
			
	});
</script>
</head>
<body ng-app="myApp" ng-controller="myController">
	<table>
	   <tr>
		  <td>姓名</td>
		  <td>年龄</td>
		  <td>成绩</td>
		  <td>科目</td>
	   </tr>
	   <tr ng-repeat="entity in list">
			<td>{{entity.name}}</td>
			<td>{{entity.age}}</td>
			<td>{{entity.score}}</td>
			<td>{{entity.subjectname}}</td>
	   </tr>
	</table>
</body>
</html>

g.$http的使用

$http服务

angular内置的$http服务简单的封装了浏览器原生的XMLHttpRequest对象,可以直接同外部进行通信。

$http服务只能接受一个参数,且该参数是一个对象,这个对象主要包含一些http请求的配置内容。如:


var req = {
    method: 'POST',
    url: 'http://example.com',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    },
    data: { test: 'test' }
}

$http(req).success(function(data,header,config,status){
    //响应成功
    
}).error(function(data,header,config,status){
    //处理响应失败
});

假数据测试

新建data.json

 [
            {name:'张三',age:10,score:100,subjectname:'语文'},
            {name:'李四',age:11,score:101,subjectname:'语文1'},
            {name:'王五',age:12,score:102,subjectname:'语文2'},
            {name:'赵柳',age:13,score:103,subjectname:'语文3'}
        ]

<html>
<head>
<title>angularJs入門 循环对象数组</title>
<script src="angular.min.js"></script>
<script>
  
    //  建立模块 
	var myapp = angular.module("myApp",[]);
	
	//  创建控制器  $scope相当于public
	myapp.controller("myController",function($scope){
		
		$scope.findList = function(){
			
			$http.get("data.json").success(
				function(response){
					$scope.list=response;
				}
			);
		};	
			
	});
</script>	
</head>
<body ng-app="myApp" ng-controller="myController" ng-init="findList()">
	<table>
	   <tr>
		  <td>姓名</td>
		  <td>年龄</td>
		  <td>成绩</td>
		  <td>科目</td>
	   </tr>
	   <tr ng-repeat="entity in list">
			<td>{{entity.name}}</td>
			<td>{{entity.age}}</td>
			<td>{{entity.score}}</td>
			<td>{{entity.subjectname}}</td>
	   </tr>
	</table>
</body>
</html>

访问获取品牌列表 9101/brand/findAll.do

获取成功后通过angularJs进行分页处理

<script type="text/javascript">
		var myApp = angular.module("pinyougou",['pagination']);

        //  	创建控制器  $scope相当于public
        myApp.controller("brandController",function($scope,$http){
            

            $scope.findList = function(){
                $http.get("../brand/findAll.do").success(
                    function(response){
                        $scope.list=response;
                    }
                );
            };

            //		分页控件配置  itemsPerPage每页的条数
            $scope.paginationConf = {
                currentPage: 1,
                totalItems: 10,
                itemsPerPage: 10,
                perPageOptions: [10, 20, 30, 40, 50],
                onChange: function(){
                    $scope.reloadList();//重新加载
                }
            };

            //		重新加载列表 数据
            $scope.reloadList=function(){
               
                //		切换页码
                $scope.findPage( $scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);
            }

            $scope.findPage = function (page,size) {
                

                $http.get('../brand/findPage.do?pageNum='+page+'&pageSize='+size).success(
                    function(response){
                        $scope.list=response.rows;
                        $scope.paginationConf.totalItems=response.total;//更新总记录数
                    }
                );

            }
        });
	</script>

再表格下面添加如下语句

<!--分页-->
<tm-pagination conf="paginationConf"></tm-pagination>

后台控制器添加如下的接口:

@RequestMapping("/findPage")
public PageResult findPage(int pageNum, int pageSize){
    return brandService.findPage(pageNum,pageSize);
}

数据访问层:

 public PageResult findPage(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        Page<TbBrand> page = (Page) tbBrandMapper.selectByExample(null);
        return new PageResult(page.getTotal(),page.getResult());
    }

品牌新建

//    新增操作
$scope.save = function () {

    var methodType = "add";
    if ($scope.entity.id > 0) {
        methodType = "update";
	}
    $http.post('../brand/'+ methodType +'.do',$scope.entity).success(
        function (response) {
			if (response.success == true) {
				 //  重新加载分页信息
				 $scope.reloadList();
			} else {
				alert(response.message);
			}
        }
	);
}

表单处用ng-model进行值的绑定 

新增完成后,下次点击清空文本的内容  ng-click="entity={}" 

后端代码:

 @RequestMapping("/add")
    public Result add(@RequestBody TbBrand tbBrand){
        try {
            brandService.add(tbBrand);
            return new Result(true,"创建成功");
        } catch (Exception e){
            log.info("BrandController.add",e);
            e.printStackTrace();
            return new Result(false,"创建失败");
        }
    }

品牌的修改

需要先实现品牌的查询和显示 

 $scope.findOne = function (id){

   $http.get("../brand/findOne.do?id="+id).success(
    function (response) {
		$scope.entity = response;
    }
  );
}

 


品牌的删除操作

需要确定当前的操作对象用$event监控,如果选中push,未选中计算取消勾选的那个元素的下表,然后剔除出数组

 //		删除操作
            $scope.selectIdLists = [];
            $scope.updateSelection = function ($event,id) {

                if ($event.target.checked) {
                    $scope.selectIdLists.push(id);
                } else {
                    //	 取消勾选时,提出选中的元素
                    var index = $scope.selectIdLists.indexOf(id);
                    $scope.selectIdLists.splice(index,1);
                }
            }

            $scope.deleteBatch = function (){


                $http.get("../brand/delete.do?ids="+$scope.selectIdLists).success(
                    function (response) {
                        if (response.success == true) {
                            $scope.reloadList();
                        } else {
                            alert(response.message);
                        }
                    }
                );
            }

后台实现代码的删除

 /**
    * 批量删除
    * @Description:
    * @Author: smileTimLi
    * @Date: 2018/12/22
    */
    @RequestMapping("/delete")
    public Result DeleteBatch(Long[] ids){
        try {
            brandService.deleteBatch(ids);
            return new Result(true,"删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false,"删除失败");
        }
    }

第三部分 angularJs实现业务层代码 (service)

引入背景: 

     使用$angular.controller进行后台服务的调用,如果调用页面比较多,需要写多个重复的调用,引入service调用,将路径抽象出来

抽象angularJs的控制器

$controller('baseController',{$scope:$scope});//伪继承

第一步:基础js:

base.js和base_pagination.js

var app = angular.module("pinyougou",[]); -- 没有分页的页面引入这个js
var app = angular.module("pinyougou",['pagination']); -- 有分页的页面引入这个js

第二步:基础js: 

baseController.js 中第一行要引入$scope

 //品牌控制层 
app.controller('baseController' ,function($scope){	
	
    //重新加载列表 数据
    $scope.reloadList=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.reloadList();//重新加载
     	 }
	}; 
	
	$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.jsonToString=function(jsonString,key){
		
		var json= JSON.parse(jsonString);
		var value="";
		
		for(var i=0;i<json.length;i++){
			if(i>0){
				value+=",";
			}			
			value +=json[i][key];			
		}
				
		return value;
	}
	
});	

第三步:根据业务区分业务代码

    此处实现controller控制器之间的相互集成的关系 【伪继承】实质就是$controller的传递和共用$scope

 //控制层 
app.controller('brandController' ,function($scope,$controller   ,brandService){	
	
	$controller('baseController',{$scope:$scope});//继承
	
    //读取列表数据绑定到表单中  
	$scope.findAll=function(){
		brandService.findAll().success(
			function(response){
				$scope.list=response;
			}			
		);
	}    
	
	//分页
	$scope.findPage=function(page,rows){			
		brandService.findPage(page,rows).success(
			function(response){
				$scope.list=response.rows;	
				$scope.paginationConf.totalItems=response.total;//更新总记录数
			}			
		);
	}
	
	//查询实体 
	$scope.findOne=function(id){				
		brandService.findOne(id).success(
			function(response){
				$scope.entity= response;					
			}
		);				
	}
	
	//保存 
	$scope.save=function(){				
		var serviceObject;//服务层对象  				
		if($scope.entity.id!=null){//如果有ID
			serviceObject=brandService.update( $scope.entity ); //修改  
		}else{
			serviceObject=brandService.add( $scope.entity  );//增加 
		}				
		serviceObject.success(
			function(response){
				if(response.success){
					//重新查询 
		        	$scope.reloadList();//重新加载
				}else{
					alert(response.message);
				}
			}		
		);				
	}
	
	 
	//批量删除 
	$scope.dele=function(){			
		//获取选中的复选框			
		brandService.dele( $scope.selectIds ).success(
			function(response){
				if(response.success){
					$scope.reloadList();//刷新列表
					$scope.selectIds=[];
				}						
			}		
		);				
	}
	
	$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;//更新总记录数
			}			
		);
	}
    
});	

第四步:抽取公共的service.js

//服务层
app.service('brandService',function($http){
	    	
	//读取列表数据绑定到表单中
	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.findOne=function(id){
		return $http.get('../brand/findOne.do?id='+id);
	}
	//增加 
	this.add=function(entity){
		return  $http.post('../brand/add.do',entity );
	}
	//修改 
	this.update=function(entity){
		return  $http.post('../brand/update.do',entity );
	}
	//删除
	this.dele=function(ids){
		return $http.get('../brand/delete.do?ids='+ids);
	}
	//搜索
	this.search=function(page,rows,searchEntity){
		return $http.post('../brand/search.do?page='+page+"&rows="+rows, searchEntity);
	}    
	//下拉列表数据
	this.selectOptionList=function(){
		return $http.get('../brand/selectOptionList.do');
	}
	
});

模糊查询的实现

<div class="has-feedback">
	品牌名称:<input ng-model="searchEntity.name"> 
    品牌首字母:<input ng-model="searchEntity.firstChar">
	<button  class="btn btn-default" ng-click="reloadList()">查询</button>
</div>

searchEntity的实例化

java代码的实现以及业务层的模糊查询
@RequestMapping("/search")
    public PageResult search(@RequestBody TbBrand brand,int page,int size){
        return brandService.findPage(brand, page, size);
    }
@Override
    public PageResult findPage(TbBrand brand, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);

        TbBrandExample example = new TbBrandExample();
        Criteria criteria = example.createCriteria();

        if(brand!=null){
            if(brand.getName()!=null && brand.getName().length()>0){
                criteria.andNameLike("%"+brand.getName()+"%");
            }
            if(brand.getFirstChar()!=null && brand.getFirstChar().length()>0){
                criteria.andFirstCharLike("%"+brand.getFirstChar()+"%");
            }
        }

        Page<TbBrand> page = (Page) tbBrandMapper.selectByExample(example);
        return new PageResult(page.getTotal(),page.getResult());
    }

规格模板的使用

/**
 * @program: pinyougou_parent
 * @description: 规格和规格内容组合实体类
 * @author: smileTimLi
 * @create: 2018-12-23 12:34
 **/
@Data
@EqualsAndHashCode(callSuper = false)
public class Specification implements Serializable {
    private static final long serialVersionUID = -2404762998490659524L;

    private TbSpecification specification;
    private List<TbSpecificationOption> specificationOptionList;
}
/**
	 * 组合增加
	 * @param specification
	 * @return
	 */
	@RequestMapping("/add")
	public Result add(@RequestBody Specification specification){
		try {
			specificationService.add(specification);
			return new Result(true, "增加成功");
		} catch (Exception e) {
			e.printStackTrace();
			return new Result(false, "增加失败");
		}
	}

 specification.html

<!-- 编辑窗口 -->
<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.specification.specName">
                        </td>
                    </tr>
                </table>

                <!-- 规格选项 -->
                <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>
                    <th class="sorting">规格选项</th>
                    <th class="sorting">排序</th>
                    <th class="sorting">操作</th>
                    </thead>
                    <tbody>
                    <tr ng-repeat="pojo in entity.specificationOptionList">
                        <td>
                            <input class="form-control" placeholder="规格选项" ng-model="pojo.optionName">
                        </td>
                        <td>
                            <input class="form-control" placeholder="排序" ng-model="pojo.orders">
                        </td>
                        <td>
                            <button type="button" class="btn btn-default" title="删除" ng-click="delOption($index)"><i
                                    class="fa fa-trash-o"></i> 删除
                            </button>
                        </td>
                    </tr>
                    </tbody>
                </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>

specificationController.js

// 选项添加新的一行
	$scope.addTableRow = function(){
		$scope.entity.specificationOptionList.push({});
	}

	$scope.delOption = function(id) {
        var index = $scope.entity.specificationOptionList.indexOf(id);
        $scope.entity.specificationOptionList.splice(index,1);
	}

新增方法中需要注意

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

select2的使用 -- 添加后自动排重

引入select2.js

	<script type="text/javascript" src="../js/angular-select2.js"></script>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="typeTemplateController" ng-init="findBrandList();findSpecificationList()">

弹框中需要注意的

<!-- 编辑窗口 -->
<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 select2 select2-model="entity.brandIds" config="brandList" multiple placeholder="选择品牌(多选)" class="form-control" type="text"/>
                </td>
             </tr>
             <tr>
                <td>关联规格</td>
                <td>
                  <input select2 select2-model="entity.specIds" config="specificationList" multiple placeholder="选择规格(多选)" class="form-control" type="text"/>
                </td>
             </tr>  
             
             <tr>
                <td>扩展属性</td>
                <td>
                   <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"  width="800px">
                     <thead>
                        <tr>
                            <td><input type="checkbox" class="icheckbox_square-blue"></td>
                           <td>属性名称</td>                          
                           <td>操作</td>
                        </tr>
                     </thead>
                     <tbody>
                        <tr ng-repeat="pojo in entity.customAttributeItems">
                           <td><input type="checkbox" class="icheckbox_square-blue" ng-model="pojo.id" ></td>
                           <td><input class="form-control" placeholder="属性名称" ng-model="pojo.text"></td>
                           <td><button type="button" class="btn btn-default" title="删除" ng-click="delOption($index)"><i class="fa fa-trash-o"></i> 删除</button></td>
                        </tr>
                     </tbody>
                  </table>   
           
                </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>

控制层头部需要引入其他的service

app.controller('typeTemplateController' ,function($scope,$controller,typeTemplateService,brandService,specificationService)
 $scope.brandList = {data: []};  -- 对应config,是数据源,因为加载慢,必须进行初始化
 $scope.specificationList = {data: []};


$scope.findBrandList = function(){
       brandService.selectBrandList().success(
           function (response) {
               $scope.brandList={data: response};
           }
    );
   }
$scope.findSpecificationList = function(){
       specificationService.selectSpecificationList().success(
           function(response){
               $scope.specificationList = {data: response};;
   });
   }

json数据在前台列表中的显示

     $scope.jsonToString=function(jsonString,key){
		
		var json= JSON.parse(jsonString);
		var value="";
		
		for(var i=0;i<json.length;i++){
			if(i>0){
				value+=",";
			}			
			value +=json[i][key];			
		}
				
		return value;
	}

 html中引用

{{jsonToString(entity.specIds,"text")}}

页面就可以正常显示 

猜你喜欢

转载自blog.csdn.net/qq_35275233/article/details/84928020