• 品优购_day03


    品优购_day03

    1. 自定义服务

    自定义服务,而服务会封装一些操作。在不同的控制器中可以调用同一个服务,这样服务的代码将会被重用。页面需要用到该服务时,直接引入即可。

    <script type="text/javascript" src="../js/base_pagination.js"></script>
    
    同时body标签要指定ng-app="pinyougou"
    
    • base_pagination.js
    var app=angular.module('pinyougou',['pagination']);
    //分页,定义模块时引入pagination模块
    

    再用app定义不同的Service服务层,如:

    • brandService.js
    app.service('brandService',function($http){  	
    	
    	this.findAll=function(){
    		return $http.get('../brand/findAll.do');		
    	}
    }
    

    Controller控制层再引入需要的服务即可,如:

    • brandController.js
    //控制层 
    app.controller('brandController' ,function($scope,brandService){	 
    	brandService.findAll=function(){
    		brandService.findAll().success(
    			function(response){
    				$scope.list=response;
    			}			
    		);
    	}  
    

    2. 控制器继承

    有些功能是每个页面都有可能用到的,比如分页,复选等等,如果我们再开发另一个功能,还需要重复编写,可通过继承的方式让这些通用的功能只写一次。

    • 建立父控制器baseController.js
    app.controller('baseController' ,function($scope){	
       
    	$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);
    		}
    }  
    
    • brandController.js可继承baseController.js
     //控制层 
    app.controller('brandController' ,function($scope,$controller,brandService){	
    	
    	$controller('baseController',{$scope:$scope});
        //$controller也是angular提供的一个服务,可以实现伪继承,实际上就是与baseController共享$scope
    	
    	$scope.findAll=function(){
    		brandService.findAll().success(
    			function(response){
    				$scope.list=response;
    			}			
    		);
    	}    
    

    由于brandController继承了baseController,所以brandPro.html要引入baseController.js,理论上要在brandController.js前引入,实测引入位置在引入brandController.js之前之后都可以。

    3. 代码生成器

    可使用《黑马程序员代码生成器2.4》来完成基础代码的编写,生成后将代码拷贝到工程中,步骤如下:

    1. 将HeimaCodeUtil_V2.4_32文件夹拷贝到不含中文和空格的目录下;

    2. 运行heima_code_util.exe,填写对应信息,先点击测试连接,成功后选择数据库即可;

    1. 点击下一步,选择模板为SSM+dubbox+angularJS(服务层+WEB层),选择代码生成路径,点击生成代码,然后拷贝代码到工程即可。

      这个模板不会生成数据访问层和实体类,因为之前已经用逆向工程完成了数据访问层与实体类的生成。

    4. 代码编写重难点

    4.1 新增规格选项行

    1. specification.html

    给新建规格选项按钮添加addTableRow()方法:

    <button type="button" class="btn btn-default" title="新建"  ng-click="addTableRow()"><i class="fa fa-file-o"></i> 新增规格选项</button>
    

    修改specification.html 新建按钮,弹出窗口时对entity进行初始化,可以清空上次添加规格遗留的内容;另外如果不对entity初始化向集合添加数据时会出错。

    <button type="button" class="btn btn-default" ng-click="entity={'specificationOptionList':[]}" title="新建" data-toggle="modal" data-target="#editModal" ><i class="fa fa-file-o"></i> 新建</button>
    
    • 如何初始化entity?

    entity是一个组合,包含TbSpecification和List

    一开始是再js中初始化:

    $cope.entity.specificationOptionList=[];//这种写法是错误的,因为entity为null
    $scope.entity={specification:{},specificationOptionList:[]};//定义entity初始结构,也可写为$scope.entity={specificationOptionList:[]},specification:{}可省略,因为specification不是一个集合。

    由于每次弹出新建规格窗口时要清空输入框中的内容,所以改到了在每次点击新建按钮时初始化。

    1. 绑定编辑框的内容

    新增规格,数据分为两部分,一部分是规格名称,可封装到specification这个pojo中,另一部分是规格选项集合specificationOptionList;再将这两部分数据封装到一个对象entity中。

    <input ng-model="entity.specification.specName" class="form-control" placeholder="规格名称" >
    
    <input ng-model="tbSpecificationOption.optionName"  class="form-control" placeholder="规格选项" > 
    <input ng-model="tbSpecificationOption.orders" class="form-control" placeholder="排序"> 
    
    1. specificationController.js
    $scope.addTableRow=function(){
    		$scope.entity.specificationOptionList.push({});
    		//specificationOptionList的格式为[{},{}...]
    }
    

    4.2 删除规格选项行

    实现思路:在规格选项每一行将索引值传递给specificationOptionList集合,在集合中删除。

    1. 修改删除按钮,传递当前行索引值
    	<button type="button" class="btn btn-default" title="删除" ng-click="deleTableRow($index)"><i class="fa fa-trash-o"></i> 删除</button>
    
    
    1. specificationController.js
    $scope.deleTableRow=function(index){
     	$scope.entity.specificationOptionList.splice(index,1);
    }
    

    4.3 保存新增规格数据

    实现思路:规格和规格选项数据合并成一个对象entity来传递,则需要用一个组合pojo来接收传递过来的对象。在业务逻辑中,得到组合对象中的规格和规格选项列表,先插入规格数据到tb_specification返回规格id,然后循环插入规格选项数据到tb_specification_option,因为插入规格选项时需要规格id。

    1. 插入规格后,获取规格id

      在TbSpecificationMapper.xml中的insert节点插入selectKey获取刚插入的规格id。

    <insert id="insert" parameterType="com.pinyougou.pojo.TbSpecification" >
        
      	<selectKey resultType="java.lang.Long" order="AFTER" keyProperty="id">
      		SELECT LAST_INSERT_ID() AS ID
      	</selectKey>
        
        insert into tb_specification (id, spec_name)
        values (#{id,jdbcType=BIGINT}, #{specName,jdbcType=VARCHAR})
      </insert>
    
    1. 建立组合pojo
    public class SpecificationAndOption implements Serializable {
    	private TbSpecification specification;//规格
    	private List<TbSpecificationOption> specificationOptionList;//规格选项
        //......get/set
    }
    
    1. 业务层SpecificationService

      插入规格后,获取到了规格id,插入规格选项前要先设置规格选项的规格id。

    public void add(SpecificationAndOption sao) {
    		specificationMapper.insert(sao.getSpecification());//插入规格
    		for(TbSpecificationOption tso:sao.getSpecificationOptionList()) {
    			//注意这里要设置id
    			tso.setSpecId(sao.getSpecification().getId());
    			specificationOptionMapper.insert(tso);
    		}
    	}
    

    4.4 品牌下拉列表(select2组件)

    1. 认识select2

    页面使用要引入select2的js文件。

    1. 在type_template.html 用select2组件实现多选下拉框
    <input select2  select2-model="entity.brandIds" config="brandList" multiple placeholder="选择品牌(可多选)" class="form-control" type="text"/>	
    

    select2 表示它是一个多选框;multiple 表示可多选;config用于配置数据来源;select2-model用于指定用户选择后提交的变量。

    1. TbBrandMapper.xml中添加SQL语句配置

    查询出的数据格式如下: [{"id":1,"text":"联想"},{"id":3,"text":"三星"}],所以用List里面封装Map。

    <select id="selectOptionList"  resultType="java.util.Map" >
    select id,name as text from tb_brand
    //因为id,text这两个key的名称是固定的
    </select>
    

    4.5 扩展属性

    • type_template.html

    点击“新建”,执行实体的初始化操作:ng-click="entity={'customAttributeItems':[]}",点击“新增扩展属性”时增加一行:ng-click="addTableRow()"

    4.6 根据id查询模板

    1. typeTemplateController.js

      查询模板实体

    $scope.findOne=function(id){				
    		typeTemplateService.findOne(id).success(
    			function(response){
    				$scope.entity= response;				$scope.entity.brandIds=JSON.parse($scope.entity.brandIds);
    //将json字符串转换为json对象
    //转换品牌列表	
                   $scope.entity.specIds=JSON.parse($scope.entity.specIds);
    //转换规格列表	
                   $scope.entity.customAttributeItems=JSON.parse($scope.entity.customAttributeItems);//转换品牌列表
    			}
    		);				
    	}
    

    例如:从数据库中查询出来的规格列表是字符串:[{"id":27,"text":"网络"},{"id":32,"text":"机身内存"}],必须将其转换为json对象才能实现信息的回显(但经过我的测试发现不转换为json对象也可以显示)。

    1. baseController.js

      最终页面显示的数据不是json字符串,而是text属性值,以","分割,所以需要从json字符串提取属性值。

    //提取json字符串数据中的某个属性,返回拼接字符串,以逗号分隔
    	$scope.json2String=function(jsonStr,key){
    		var json=JSON.parse(jsonStr);//将json字符串转为json对象
    		var str="";
    		for(var i=0;i<json.length;i++){
    			if(i>0){
    				str+=",";
    			}
    			str+=json[i][key];//获取第i个键名为key的值
    			//[{"id":27,"text":"网络"},{"id":32,"text":"机身内存"}]
    		}
    		return str;
    	}
    
    1. type_template.html
    //调用方法转换json字符串
    <td>{{json2String(entity.brandIds,'text')}}</td>
    <td>{{json2String(entity.specIds,'text')}}</td>				<td>{{json2String(entity.customAttributeItems,'text')}}</td>
    
  • 相关阅读:
    RTMP直播流媒体服务-开放直播快速开启推流直播
    安防摄像头互联网直播方案LiveGBS设计文档
    GB28181开放流媒体服务平台LiveGBS实际测试时问题排查
    监控摄像头进行网页直播和微信直播的技术方案
    LiveQing云端直播点播-自定义直播快照存储提供基于图片的直播服务
    浏览器低延时播放监控摄像头视频(LiveNVR播放FLV视频流)
    Javascript之计时
    Android之记账本
    Android之布局
    CSS之动态相册
  • 原文地址:https://www.cnblogs.com/ALiWang/p/12871947.html
Copyright © 2020-2023  润新知