最近,一个同事接到一个开发任务,其中有一个功能模块就是关于收货地址的,在收货地址的回显上遇到了一些麻烦,因为我之前做过收货地址的模块,因此将经验总结于下,供大家参考:
所用技术:AngularJs
一、模块功能介绍
单击选择地址弹出层后,因为没有地址信息,所以先添加地址
(图一如上 选择收货地址弹出层)
单击添加后触发事件弹出另一个弹出层,对地址信息进行编辑,此处就涉及到了省市的联动,当开启此页面时,会首先调用接口获取到省的信息列表,然后当选择省的信息列表后,会触发事件再获取到城市的信息列表,这样就能单击下拉列表框的时候显示出省市的数据
(图二如上 编辑地址弹出层)
(图三 关于省市联动的具体数据获取详情)
(图四 单击确定后返回到收货地址选择页 可进行编辑)
编辑页面和添加收货地址页面可公用一个页面,因为修改的和添加的字段信息都只一致的,最好用不同的js文件来写触发的不同事件(单击编辑后要在页面上对数据进行回显,再进行修改和保存)
二、代码详解
<!--收货地址-->
<div class="col-md-6">
<div class="form-group" data-ng-class="{'has-error': editForm.CustomerAddress.$dirty && editForm.CustomerAddress.$error.required}">
<label class="control-label col-md-3">收货地址*</label>
<!--输入框-->
<div class="col-md-7">
<input type="text" name="CustomerAddress" required ng-model="CustStoreAddress" class="form-control" placeholder="" readonly="readonly" />
</div>
<!--选择按钮-->
<div class="col-md-2">
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="OpenOrderAddressList()"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</div>
</div>
</div>
单击图一的按钮触发OpenOrderAddressList()方法,打开图一的模态框选择收货地址
//选择门店收货地址
$scope.OpenOrderAddressList = function () {
//加载收货地址列表
if ($scope.OrderInfo.CustStoreId != null) {
var model = {
storeId: $scope.OrderInfo.CustStoreId
};
$modal.open({
templateUrl: 'MallModules/SelectCustStoreAddress',
controller: 'OrderDeliveListCtrl',
size: 'lg',
resolve: {
model: function () {
return model;
}
}
}).result.then(function (result) {
if (result != null) {
$scope.CustStoreAddress = result.Address;
$scope.OrderDetail.AddressId = result.Id;
}
});
} else {
$notify.error("选择收货地址", "请先选择一个门店(客户)");
}
}
从代码中你应该能看出它在打开这个选择收货地址模态框的时候会附带传送一个参数model,里面装了一个storeId,这个参数至关重要,因为这个字段是用来在打开模态框时调用后台接口加载地址信息数据的参数。
<div class="modal-header">
<h3 class="modal-title">选择地址</h3>
</div>
<form name="editForm" action="" class="form-horizontal" ng-init="initCustStoreAdr()">
<div class="modal-body">
<div class="btn-group pull-right">
<button class="btn btn-primary" ng-click="newAddress()">添加</button>
</div>
<div class="form-body">
<div class="row">
<div class="col-md-12">
<table class="table table-striped table-bordered table-hover" id="CustStoreAdr">
<thead>
</thead>
<tbody></tbody>
</table>
<script id="actions" type="text/template">
<div class="btn-group btn-group-xs actions">
<button class="btn btn-link" data-action="editRow" title="编辑"><i class="fa fa-edit"> 编辑</i></button>
<button class="btn btn-link" data-action="deleteRow" title="删除"><i class="fa fa-edit"> 删除</i></button>
</div>
</script>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-disabled="editForm.$invalid" ng-click="getCustStoreAdr()">确认</button>
<button class="btn btn-warning" ng-click="cancel()">取消</button>
</div>
</form>
<script type="text/javascript">
$(document).ready(function () {
$(".modal").attr("modal-window", null);
});
</script>
MetronicApp.controller('OrderDeliveListCtrl', ['$rootScope', '$scope', '$filter', '$ngDataTables', '$modal', '$notify', '$datacenterapiBasic', '$modalInstance', '$apiOrderApp', 'model',
function ($rootScope, $scope, $filter, $ngDataTables, $modal, $notify, $datacenterapiBasic, $modalInstance, $apiOrderApp, model) {
$scope.model = model;
$scope.custstoreAdrTable;
//初始化地址列表
$scope.initCustStoreAdr = function () {
initCustStoreAdrTable();
}
var initCustStoreAdrTable = function () {
$scope.custstoreAdrTable = $ngDataTables.init({
src: "#CustStoreAdr",
scope: $scope,
selectable: true,
searchable: false,
noCount: true,
columns: [
{ title: '省份', data: 'ProName', width: '70px' },
{ title: '城市', data: 'CityName', width: '70px' },
{ title: '地址', data: 'Address', width: '150px' }
],
getData: function (paging, success) {
$scope.model.Page = paging;
//调用后台接口
$apiOrderApp.GetDeliveListByStoreId($scope.model, success);
},
search: {
width: 100,
actionTemplate: "#actions"
}
});
}
//选定收货地址
$scope.getCustStoreAdr = function () {
var rows = $scope.custstoreAdrTable.getSelectedData();
if (rows.length == 1) {
var row = rows[0];
var entity;
if (typeof row == "object") {
entity = row;
} else {
entity = $scope.custstoreAdrTable.data[row];
};
$modalInstance.close(entity);
}
else {
$notify.info("收货地址", "请选择一条收货地址信息。");
}
}
//添加地址
$scope.newAddress = function () {
$modal.open({
templateUrl: 'MallModules/AddAddress',
controller: 'OrderDeliveAddCtrl',
size: 'lg',
resolve: {
entity: function () {
return model;
}
}
}).result.then(function (result) {
if (result != null) {
if (result.Success) {
$notify.success('操作成功', '已成功添加了数据!');
$scope.custstoreAdrTable.refresh(true);
} else {
$notify.error('操作失败', result.AllMessages);
}
}
});
}
//编辑地址
$scope.editRow = function (row) {
var editEntity;
if (typeof row == "object") {
editEntity = row;
} else {
editEntity = $scope.custstoreAdrTable.data[row];
}
$modal.open({
templateUrl: 'MallModules/AddAddress',
controller: 'OrderDeliveEditCtrl',
size: 'lg',
resolve: {
id: function () {
return editEntity.Id;
}
}
}).result.then(function (result) {
if (result != null) {
if (result.Success) {
$notify.success('操作成功', '已成功编辑了数据!');
$scope.custstoreAdrTable.refresh(true);
} else {
$notify.error('操作失败', result.AllMessages);
}
}
});
}
//删除地址
$scope.deleteRow = function (row) {
var entity;
if (typeof row == "object") {
entity = row;
} else {
entity = $scope.custstoreAdrTable.data[row];
}
var id = [entity.Id];
$notify.confirm("删除确认", "您确认要删除选中的收货地址吗?", function () {
$apiOrderApp.DeleteOrderDeliveryAddress(id, function (result) {
if (result.Success) {
$notify.success('操作成功', '已成功删除了数据!');
$scope.custstoreAdrTable.refresh(true);
} else {
$notify.error('操作失败', result.AllMessages);
}
});
});
}
//页面点击取消按钮触发事件
$scope.cancel = function (row) {
$modalInstance.close(null);
}
}]);
上面的两段代码就是选择收货地址的前端相关代码,此处我只对添加地址和编辑地址进行相关介绍:
$apiOrderApp.GetDeliveListByStoreId($scope.model, success);这一行代码你应该看到了,这就是上面说过的调用后台的接口以model中的storeId为参数,获取相关地址信息,有则显示出来,如果没有那只能添加了,单击图一添加按钮触发添加地址事件,此处你会发现它也携带了一个参数,这个参数正是刚才传过来的那个model,它会被带到添加收货地址页(图二),被当作填写完表单信息后单击保存时,调用后台几口插入数据所用的参数。
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label class="col-md-2 control-label">省份*:</label>
<div class="col-md-4" data-ng-class="{'has-error': editForm.StateName.$dirty && editForm.StateName.$error.required}">
<select required name="StateName" class="form-control" ng-model="province" ng-change="changeProvince()" ng-options="m as m.Name for m in provinceList">
<option value="">--请选择--</option>
</select>
</div>
<label class="col-md-2 control-label">城市*:</label>
<div class="col-md-4" data-ng-class="{'has-error': editForm.CityName.$dirty && editForm.CityName.$error.required}">
<select required name="CityName" class="form-control" ng-model="City" ng-change="changeCity()" ng-options="m as m.Name for m in cityList">
<option value="">--请选择--</option>
</select>
</div>
</div>
</div>
</div>
MetronicApp.controller('OrderDeliveAddCtrl', ['$scope', '$filter', '$ngDataTables', '$apiOrderApp', '$modal', '$location', '$notify', '$datacenterapiBasic', '$modalInstance', 'entity',
function ($scope, $filter, $ngDataTables, $apiOrderApp, $modal, $location, $notify, $datacenterapiBasic, $modalInstance, entity) {
var custStoreId = entity.storeId;
$scope.entity = {};
$scope.provinceList = [];//省份列表
$scope.cityList = []//城市列表
//加载省份列表
$datacenterapiBasic.GetTopDistrict(function (result) {
if (result.Success) {
console.log("省份数据:", result);
$scope.provinceList = result.Data;
}
});
//加载城市列表
$scope.changeProvince = function () {
$scope.cityList = [];
if ($scope.province) {
//根据省份code获取城市列表
$datacenterapiBasic.GetDistrictByParentCode($scope.province.Code, function (result) {
if (result.Success) {
console.log("province数据:", $scope.province);
console.log("城市数据:", result);
$scope.cityList = result.Data;
}
});
}
}
//保存
$scope.save = function () {
//省的编码
$scope.entity.ProCode = $scope.province.Code;
//市的编码
$scope.entity.CityCode = $scope.City.Code;
//自动设置不是默认地址
$scope.entity.IsDefault = false;
$scope.entity.CustStoreId = custStoreId;
//if (validate()) {
//调用后台api添加门店地址的接口
$apiOrderApp.AddOrderDeliveryAddress($scope.entity, function (result) {
if (result.Success) {
$notify.success('收货地址', '保存成功');
$modalInstance.close(result);
} else {
$notify.error("保存失败," + result.AllMessages);
}
});
//}
}
//返回
$scope.cancel = function () {
$modalInstance.close(null);
}
}]);
上面这两段代码就是省市联动的那块页面以及js处理事件的代码,相信你应该能够看懂,我就不详细解释了,重点在于如果在选择页面如果有数据显示,当我要进行编辑修改时的处理,单击图四中的编辑会触发编辑事件,打开的也是添加收货地址的模态框,但跟添加地址的出发的js事件是不同的,因此此处进行了js代码的分离,编辑相关的js代码如下:
MetronicApp.controller('OrderDeliveEditCtrl', ['$scope', '$filter', '$ngDataTables', '$apiOrderApp', '$modal', '$location', '$notify', '$datacenterapiBasic', 'id', '$modalInstance',
function ($scope, $filter, $ngDataTables, $apiOrderApp, $modal, $location, $notify, $datacenterapiBasic, id, $modalInstance) {
$scope.entity = null;
$scope.provinceList = null;//省的集合
$scope.provinceLists = new Array();
$scope.cityList = null;//城市集合
var Id = id;
// 地区
$datacenterapiBasic.GetTopDistrict(function (result) {
if (result.Success) {
$scope.provinceList = result.Data;
$scope.provinceLists = result.Data;
}
});
//显示省、城市等表单信息
$apiOrderApp.GetOrderDeliveryAddress(Id, function (result) {
$scope.entityData = result.Data;
if ($scope.entityData != null) {
initList($scope.entityData);
}
});
//将数据填充到弹出框中
var initList = function (entityData) {
//省
for (var i = 0; i < $scope.provinceLists.length; i++) {
if ($scope.provinceLists[i].Code == entityData.ProCode) {
$scope.province = $scope.provinceLists[i];
}
}
//城市
if ($scope.province != null) {
$datacenterapiBasic.GetDistrictByParentCode($scope.province.Code, function (results) {
if (results.Success) {
$scope.cityList = results.Data;
for (var j = 0; j < results.Data.length; j++) {
if (results.Data[j].Code == entityData.CityCode) {
$scope.City = results.Data[j];
}
}
}
});
}
//其他(收货人、邮编等)
console.log(entityData);
$scope.entity = entityData;
}
//点击保存按钮触发
$scope.save = function () {
$scope.entity.ProCode = $scope.province.Code;
$scope.entity.CityCode = $scope.City.Code;
//调用后台api更改地址的接口
$apiOrderApp.UpdateOrderDeliveryAddress($scope.entity, function (fileresult) {
if (fileresult.Success) {
$notify.success('收货地址', '修改成功');
$modalInstance.close(fileresult);
}
});
}
//返回
$scope.cancel = function () {
$modalInstance.close(null);
}
//城市
$scope.changeProvince = function () {
$scope.cityList = null;
$scope.districtList = null;
if ($scope.province == null || $scope.province == undefined) {
$scope.cityList = "";
}
else {
$datacenterapiBasic.GetDistrictByParentCode($scope.province.Code, function (result) {
if (result.Success) {
$scope.cityList = result.Data;
}
})
}
}
}]);
此处我就不再过多的赘述了,看代码就完了。