品優購 第三天

規格及模板管理

1.前端分層開發

1.1 需求分析

我們在上次課學習了angularJS並完成的品牌管理的增刪改查功能。但是我們看代碼,JS和html都放在一起,並不利於我們後期的維護。我們可以在前端代碼中也運用MVC的設計模式,將代碼進行分離,提高程序的可維護性。

1.2 自定義服務

在 AngularJS 中,服務是一個函數或對象,可在你的 AngularJS 應用中使用。我們在上次課中使用了內置服務$http .其實我們也可以自己來定義服務,而服務會封裝一些操作。我們在不同的控制器中可以調用同一個服務,這樣服務的代碼將會被重用。

我們現在就修改一下我們的品牌管理代碼,使用自定義服務。

var app=angular.module('pinyougou', ['pagination']);//定義模塊

//品牌服務層

app.service('brandService',function($http){

//讀取列表數據綁定到表單中

this.findAll=function(){

return $http.get('../brand/findAll.do');

}

//其它方法省略.......

});

//品牌控制層

app.controller('brandController' ,function($scope,brandService){

//讀取列表數據綁定到表單中

$scope.findAll=function(){

brandService.findAll().success(

function(response){

$scope.list=response;

}

);

}

//其它方法省略........

});

1.3代碼分離

我們剛才已經將與後端交互的部分放入自定義服務,目的是不同的控制層都可以重複調用服務層方法。所以我們還需要將代碼分離出來,以便調用。

1.3.1 前端基礎層

在pinyougou-manager-web工程js下創建base.js

var app=angular.module('pinyougou',[]);

創建base_pagination.js

var app=angular.module('pinyougou',['pagination']);

一個用於不需要分頁功能的頁面,一個用於需要分頁功能的頁面.

1.3.2 前端服務層

在pinyougou-manager-web工程js下創建service文件夾。創建brandService.js

//品牌服務層

app.service('brandService',function($http){

//讀取列表數據綁定到表單中

this.findAll=function(){

return $http.get('../brand/findAll.do');

}

//其它方法省略........

});

1.3.3 前端控制層

在pinyougou-manager-web的js文件夾下創建brandController.js

//品牌控制層

app.controller('brandController' ,function($scope,brandService){

//讀取列表數據綁定到表單中

$scope.findAll=function(){

brandService.findAll().success(

function(response){

$scope.list=response;

}

);

}

//其它方法省略........

});

1.3.4 修改頁面

去掉brand.html原來的JS代碼,引入剛才我們建立的JS

(3) 選擇數據庫類型為 MYSQL ,輸入用戶名和密碼後點擊“測試連接”按鈕,提示連接成功後選擇數據庫,點擊“下一步”。

(4)選擇模板為SSM+dubbox+angularJS(服務層+WEB層)

這個模板不會生成數據訪問層和實體類,因為我們之前已經用逆向工程完成了數據訪問層與實體類的生成。

(5)點擊生成代碼按鈕,提示成功後,到生成路徑去找生成的代碼,並拷貝到我們的工程中。

3.2代碼拷貝

將商家商品相關代碼拷貝到工程。

(1) 拷貝服務接口

(2) 拷貝服務實現類

(3) 拷貝控制器

(4) 拷貝JS

3.3安裝到本地倉庫

執行maven命令install ,將最新的品優購代碼安裝到本地倉庫

4.規格管理

4.1需求及表結構分析

4.1.1 需求

實現規格管理功能

4.1.2 表結構

tb_specification 規格表

字段

類型

長度

含義

Id

Bigint

主鍵

Spec_name

Varchar

255

規格名稱

tb_specification_option 規格選項表

字段

類型

長度

含義

Id

Bigint

主鍵

Option_name

Varchar

200

規格選項名稱

Spec_id

Bigint

30

規格ID

Orders

Int

11

排序

4.2規格列表

4.2.1 引入JS

修改pinyougou-manager-web工程的specification.html

<link>

4.2.3 指令與表達式

在body元素指定模塊名和控制器名

ng-app="pinyougou" ng-controller="specificationController" >

循環表格行

{{entity.id}}

{{entity.specName}}

<button>修改/<button>

4.3新增規格

4.3.1 新增行的實現

修改specificationController.js 新增以下代碼

//新增選項行

$scope.addTableRow=function(){

$scope.entity.specificationOptionList.push({});

}

specification.html “新建選項”按鈕

<button> 新建/<button>

注意:要修改specification.html “新建”按鈕,彈出窗口時對entity進行初始化,否則向集合添加數據時會報錯!

<button> 新建/<button>

4.3.2 刪除行的實現

實現思路:在每一行將索引值傳遞給集合,在集合中刪除。

修改specificationController.js 新增以下代碼

//批量選項刪除

$scope.deleTableRow=function(index){

$scope.entity.specificationOptionList.splice(index,1);//刪除

}

修改每行的刪除按鈕

<button> 刪除/<button>

$index 用於獲取ng-repeat指令循環中的索引。

4.3.3 提交保存

實現思路:我們將規格和規格選項數據合併成一個對象來傳遞,這時我們需要用一個對象將這兩個對象組合起來。在業務邏輯中,得到組合對象中的規格和規格選項列表,插入規格返回規格ID,然後循環插入規格選項。

(1) 我們要增加規格選項,必須要知道新增規格的ID, 所以我們在修改pinyougou-dao 的TbSpecificationMapper.xml ,在insert節點後添加如下配置

<insert>

<selectkey>

SELECT LAST_INSERT_ID() AS id

insert into tb_specification (id, spec_name)

values (#{id,jdbcType=BIGINT}, #{specName,jdbcType=VARCHAR})

(2)在pinyougou-pojo 建立com.pinyougou.pojogroup包,包下建立Specification類

package com.pinyougou.pojogroup;

import java.io.Serializable;

import java.util.List;

import com.pinyougou.pojo.TbSpecification;

import com.pinyougou.pojo.TbSpecificationOption;

/**

* 規格組合實體類

* @author Administrator

*

*/

public class Specification implements Serializable {

private TbSpecification specification;

private List<tbspecificationoption> specificationOptionList;/<tbspecificationoption>

public TbSpecification getSpecification() {

return specification;

}

public void setSpecification(TbSpecification specification) {

this.specification = specification;

}

public List<tbspecificationoption> getSpecificationOptionList() {/<tbspecificationoption>

return specificationOptionList;

}

public void setSpecificationOptionList(List<tbspecificationoption> specificationOptionList) {/<tbspecificationoption>

this.specificationOptionList = specificationOptionList;

}

}

(%1) 修改pinyougou-sellergoods-interface的SpecificationService.java

/**

* 增加

*/

public void add(Specification specification);

(%1) 修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 增加

*/

@Override

public void add(Specification specification) {

specificationMapper.insert(specification.getSpecification());//插入規格

//循環插入規格選項

for(TbSpecificationOption specificationOption:specification.getSpecificationOptionList()){ specificationOption.setSpecId(specification.getSpecification().getId());//設置規格ID specificationOptionMapper.insert(specificationOption);

}

}

(5)修改pinyougou-manager-web的SpecificationController.java

/**

* 增加

* @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, "增加失敗");

}

}

(%1) 修改頁面specification.html

綁定規格名稱

<table>

規格名稱

/<table>

綁定保存按鈕事件

<button>保存/<button>

4.4修改規格

4.4.1 獲取規格數據

實現思路:通過規格ID,到後端查詢規格和規格選項列表,然後通過組合實體類返回結果

(1)修改pinyougou-sellergoods-interface的SpecificationService.java

/**

* 根據ID獲取實體

* @param id

* @return

*/

public Specification findOne(Long id);

(2)修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 根據ID獲取實體

* @param id

* @return

*/

@Override

public Specification findOne(Long id){

//查詢規格

TbSpecification tbSpecification = specificationMapper.selectByPrimaryKey(id);

//查詢規格選項列表

TbSpecificationOptionExample example=new TbSpecificationOptionExample();

Criteria criteria = example.createCriteria();

criteria.andSpecIdEqualTo(id);//根據規格ID查詢

List<tbspecificationoption> optionList = specificationOptionMapper.selectByExample(example);/<tbspecificationoption>

//構建組合實體類返回結果

Specification spec=new Specification();

spec.setSpecification(tbSpecification);

spec.setSpecificationOptionList(optionList);

return spec;

}

(3)修改pinyougou-manager-web的SpecificationController.java

@RequestMapping("/findOne")

public Specification findOne(Long id){

return specificationService.findOne(id);

}

(%1) 修改頁面specification.html 中列表的修改按鈕

<button>修改/<button>

4.4.2 保存修改結果

(1)修改pinyougou-sellergoods-interface的SpecificationService.java

/**

* 修改

*/

public void update(Specification specification);

(2)修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 修改

*/

@Override

public void update(Specification specification){

//保存修改的規格

specificationMapper.updateByPrimaryKey(specification.getSpecification());//保存規格

//刪除原有的規格選項

TbSpecificationOptionExample example=new TbSpecificationOptionExample();

com.pinyougou.pojo.TbSpecificationOptionExample.Criteria criteria = example.createCriteria();

criteria.andSpecIdEqualTo(specification.getSpecification().getId());//指定規格ID為條件

specificationOptionMapper.deleteByExample(example);//刪除

//循環插入規格選項

for(TbSpecificationOption specificationOption:specification.getSpecificationOptionList()){

specificationOption.setSpecId(specification.getSpecification().getId());

specificationOptionMapper.insert(specificationOption);

}

}

(3)修改pinyougou-manager-web的SpecificationController.java

/**

* 修改

* @param specification

* @return

*/

@RequestMapping("/update")

public Result update(@RequestBody Specification specification){

try {

specificationService.update(specification);

return new Result(true, "修改成功");

} catch (Exception e) {

e.printStackTrace();

return new Result(false, "修改失敗");

}

}

(4)修改specification.js的save方法

//保存

$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);

}

}

);

}

4.5刪除規格

實現思路:我們要刪除規格的同時,還要記得將關聯的規格選項刪除掉。

4.5.1 後端代碼

修改pinyougou-sellergoods-service的SpecificationServiceImpl.java

/**

* 批量刪除

*/

@Override

public void delete(Long[] ids) {

for(Long id:ids){

specificationMapper.deleteByPrimaryKey(id);

//刪除原有的規格選項

TbSpecificationOptionExample example=new TbSpecificationOptionExample();

com.pinyougou.pojo.TbSpecificationOptionExample.Criteria criteria = example.createCriteria();

criteria.andSpecIdEqualTo(id);//指定規格ID為條件

specificationOptionMapper.deleteByExample(example);//刪除

}

}

4.5.2 前端代碼

修改pinyougou-manager-web的specification.html

列表的複選框

刪除按鈕

<button> 刪除/<button>

5.模板管理

5.1 需求及表結構分析

5.1.1 需求分析

首選我們需要理解模板的作用。模板主要有兩個:

1是用於關聯品牌與規格

2定義擴充屬性

5.1.2 表結構分析

tb_type_template 模板表

字段

類型

長度

含義

Id

Bigint

主鍵

name

Varchar

80

模板名稱

Spec_ids

Varchar

1000

關聯規格(json格式)

brand_ids

Varchar

1000

關聯品牌(json格式)

custom_attribute_items

Varchar

2000

擴展屬性

5.2 模板列表

5.2.1 引入JS

修改type_template.html ,引入JS

<link>

5.2.3 指令與表達式

{{entity.id}}

{{entity.name}}

{{entity.brandIds}}

{{entity.specIds}}

{{entity.customAttributeItems}}

<button>修改/<button>

5.3 品牌下拉列表

在彈出窗口中有個品牌下拉列表,要求品牌是可以選擇多個,這與我們之前的單選的下拉列表是不同的。我們要想實現這個功能,需要使用select2 組件來完成。

5.2.1 認識select2

我們來看例子:我們需要的就是這樣可以多選的下拉框

5.2.2 顯示品牌下拉列表(靜態)

(1)修改 type_template.html 引入JS

<link>

<link>

multiple 表示可多選

Config用於配置數據來源

select2-model用於指定用戶選擇後提交的變量

最終實現效果如下:

5.2.3 後端數據支撐

我們現在讓這個下拉列表的數據從數據庫中提取,修改後端代碼

(1)pinyougou-dao 工程 ,在TbBrandMapper.xml中添加SQL語句配置

<select>

select id,name as text from tb_brand

(2)在pinyougou-dao 的TbBrandMapper中添加方法定義

List selectOptionList();

(3)修改pinyougou-sellergoods-interface 的BrandService.java,增加方法定義

/**

* 品牌下拉框數據

*/

List selectOptionList();

(4)修改pinyougou-sellergoods-service的BrandServiceImpl.java,增加方法

/**

* 列表數據

*/

public List selectOptionList() {

return brandMapper.selectOptionList();

}

(5)修改pinyougou-manager-web的BrandController.java

@RequestMapping("/selectOptionList")

public List selectOptionList(){

return brandService.selectOptionList();

}

(%1) 修改pinyougou-manager-web的brandService.js

//下拉列表數據

this.selectOptionList=function(){

return $http.get('../brand/selectOptionList.do');

}

(%1) 修改pinyougou-manager-web的typeTemplateController.js

因為我們在模板控制層中需要使用品牌服務層的方法,所以需要添加依賴注入

//控制層

app.controller('typeTemplateController' ,function($scope,$controller ,typeTemplateService ,brandService){

使用品牌服務方法實現查詢,結果賦給變量

$scope.brandList={data:[]};//品牌列表

//讀取品牌列表

$scope.findBrandList=function(){

brandService.selectOptionList().success(

function(response){

$scope.brandList={data:response};

}

);

}

(8)修改type_template.html ,添加JS引入

5.4 規格下拉列表

(代碼略,參照品牌下拉列表的實現步驟 )

5.5 擴展屬性

5.5.1 增加行

在typeTemplateController.js中新增代碼

//新增擴展屬性行

$scope.addTableRow=function(){

$scope.entity.customAttributeItems.push({});

}

在type_template.html中的“新建”按鈕,執行實體的初始化操作

<button> 新建/<button>

修改“新增擴展屬性按鈕”

<button> 新增擴展屬性/<button>

循環表格

<button> 刪除/<button>

5.5.2 刪除行

實現思路:在每一行將索引值傳遞給集合,在集合中刪除。

修改typeTemplateController.js新增以下代碼

//刪除擴展屬性行

$scope.deleTableRow=function(index){

$scope.entity.customAttributeItems.splice(index,1);//刪除

}

修改每行的刪除按鈕

<button> 刪除/<button>

$index 用於獲取ng-repeat指令循環中的索引。

5.6 新增模板

修改type_template.html ,綁定文本框

模板名稱

保存按鈕

<button>保存/<button>

5.7 修改模板

修改typeTemplateController.js的findOne方法

//查詢實體

$scope.findOne=function(id){

typeTemplateService.findOne(id).success(

function(response){

$scope.entity= response;

$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對象才能實現信息的回顯。

5.8 刪除模板

修改type_template.html

表格中的複選框

刪除按鈕

<button>

刪除

5.9 優化模板列表的顯示

我們現在完成的列表中都是以JSON格式顯示的,不利於用戶的查詢。

我們需要將信息以更友好的方式展現出來,如下圖形式

我們需要將一個json字符串中某個屬性的值提取出來,用逗號拼接成一個新的字符串。這樣的功能比較常用,所以我們將方法寫到baseController.js

//提取json字符串數據中某個屬性,返回拼接字符串 逗號分隔

$scope.jsonToString=function(jsonString,key){

var json=JSON.parse(jsonString);//將json字符串轉換為json對象

var value="";

for(var i=0;i<json.length>

if(i>0){

value+=","

}

value+=json[i][key];

}

return value;

}

頁面上使用該函數進行轉換

{{entity.id}}

{{entity.name}}

{{jsonToString(entity.brandIds,'text')}}

{{jsonToString(entity.specIds,'text')}} {{jsonToString(entity.customAttributeItems,'text')}}

<button>修改/<button>

/<json.length>

如果大家認為對你們有用,你們就轉發轉發,感謝大家