基于MVC的前台ExtJs树型表格的批量数据操作实现
来源:互联网 发布:汉武大帝知乎 编辑:程序博客网 时间:2024/06/16 08:47
项目背景:在项目管理信息系统中,基于软件项目的生命周期中有个很重要的模块是计划管理,通常计划管理会分成四层计划:项目范围+季度计划+月度计划
+周任务单,在范围计划界面输入就涉及到树表的应用
项目中树表实现的要求:添加同级节点行+添加子级节点行+修改+删除,其中未保存前添加节点和修改要能够批量操作,点击提交按钮,前台数据整体提交。PS:范围计划实际编辑中层级和修改会比较多,不能使用弹窗和右键菜单。效果如下:
项目基本框架:Extjs+MVC+SQLServer
Extjs的前台树形表格实现思路:前台使用Extjs的TreePanel控件,前台处理完之后数据整体提交到Controller中,Controller调用BLL层方法处理数据,数据库的操作全部使用存储过程,
Extjs前台树形表的修改+增就同级节点+增子节点的批量操作实现思路:
Step1:使用TreePanel 组件构造出想要的树表(首先得构造一个Store 和Model):
Ext.define('Plan.RangePlan.RangePlanContentMg', {
extend: 'Ext.tree.Panel',
alias: 'widget.RangePlanContentMg',
rootVisible: false,
border: false,
useArrows: true,
initComponent: function () {
var me = this;
var store = Ext.create("Plan.RangePlanStore");
store.load({
params: {
pId: 0
}
});
Ext.apply(me, {
columnLines: true,
store: store,
selModel: {
selType: 'checkboxmodel',
singleSelect: true
},
plugins: [Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 2
})],
columns: [{
xtype: 'rownumberer',
align: 'center',
width: 35,
text: "序号"
},{
xtype: 'treecolumn',
header: "模块名称",
flex: 1,
dataIndex: 'TaskName',
sortable: false,
width: 100,
editor: { xtype: 'textarea', allowBlank: false }
}, {
header: "模块描述",
dataIndex: 'TaskDesc',
flex: 1,
width: 120,
editor: { xtype: 'textarea', allowBlank: false }
}, {
header: "交付物",
dataIndex: 'DestName',
flex: 1,
width: 100,
editor: { xtype: 'textarea', allowBlank: false }
}, {
header: "验收标注",
dataIndex: 'Measurement',
flex: 1,
width: 100,
editor: { xtype: 'textarea', allowBlank: false }
}, {
id:'startime',
header: "开始日期",
dataIndex: 'StartDate',
flex: 1,
xtype: 'datecolumn',
align: 'center',
width: 100,
//将日期转化成yyyy/mm/dd格式
renderer: Ext.util.Format.dateRenderer(Ext.custom.dateFormat()),
editor: {
xtype: 'datefield',
format: 'y/m/d',
width: 100,
id: 'StartDate',
minValue: new Date(),
disabledDays: [0, 6],
disabledDaysText: 'Plants are not available on the weekends'
}
}, {
header: "结束日期",
dataIndex: 'EndDate',
flex: 1,
xtype: 'datecolumn',
align: 'center',
width: 100,
//将日期转化成yyyy/mm/dd格式
renderer: Ext.util.Format.dateRenderer(Ext.custom.dateFormat()),
editor: {
xtype: 'datefield',
format: 'y/m/d',
width: 100,
id: 'EndDate',
minValue: new Date(),
disabledDays: [0, 6],
disabledDaysText: 'Plants are not available on the weekends'
}
},
{
header: "状态",
flex: 1,
dataIndex: 'Status',
width: 70,
editor: { xtype: 'combo', allowBlank: false }
},
{
header: "计划类型",
flex: 1,
dataIndex: 'ApprovalStatus',
width: 70,
editor: { xtype: 'combo', allowBlank: false }
},
{
header: "批注",
flex: 1,
dataIndex: 'Remark',
width: 100,
editor: { xtype: 'textarea', allowBlank: false }
}],
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'button',
text: '添加同级节点',
iconCls: 'add',
tag: 'add',
handler: me.onAddRange
}, '-', {
xtype: 'button',
text: '添加子级节点',
iconCls: 'add',
tag: 'addsub',
handler: me.onAddSubRange
}, '-', {
xtype: 'button',
text: '修改',
disabled: true,
iconCls: 'edit',
tag: 'edit',
handler: me.onEditRange
}, '-', {
xtype: 'button',
text: '删除',
iconCls: 'delete',
tag: 'delete',
handler: me.onDeleteRange
}, '-', {
xtype: 'button',
text: "保存",
iconCls: 'save',
tag: 'save',
handler: me.onSaveRange
}, '-', {
xtype: 'button',
text: '提交',
disabled:true,
iconCls: 'export',
tag: 'submit',
handler: me.onSubmitRange
}]
}]
});
me.callParent(arguments);
},
Step2:前台Js文件中写上各个按钮的Handler与上面的相呼应:
//添加同级节点
onAddRange: function (btn) {
var grid = btn.up('RangePlanContentMg');
var treeStore = grid.getStore();
var node = grid.getSelectionModel().getSelection()[0];
var pn = node.parentNode;
var id = node.parentNode.get("SeqId");
var data = {
"SeqId":null,
"ParentSeqId": node.parentNode.get("SeqId"),
"TaskName": null,
"TaskDesc": null,
"DestName": null,
"Measurement": null,
"StartDate": null,
"EndDate": null,
"Status": null,
"ApprovalStatus": null,
"Remark": null,
"leaf": true
};
var rec = Ext.create('Plan.RangePlanModel', data);
node.set('leaf', true);
pn.appendChild(rec);
},
//添加子级节点
onAddSubRange: function (btn) {
var grid = btn.up('RangePlanContentMg');
var node = grid.getSelectionModel().getSelection()[0];
var treeStore = grid.getStore();
var id = node.get('SeqId');
var data = {
"SeqId": null,
"ParentSeqId": node.get('SeqId'),
"TaskName": null,
"TaskDesc": null,
"DestName": null,
"Measurement": null,
"StartDate": null,
"EndDate": null,
"Status": null,
"ApprovalStatus": null,
"Remark": null,
"leaf": true
};
var rec = Ext.create('Plan.RangePlanModel', data);
node.set("leaf", false);
node.appendChild(rec);
node.expand();
},
//根据选中行进行编辑修改
onEditRange:function (btn) {
var grid = btn.up('RangePlanContentMg');
var records = grid.getSelectionModel().getSelection();
//var data = grid.getStore().getById(records[records.length - 1].internalId);
var data = grid.getStore().getById(records[records.length - 1].get("SeqId"));
if (records.length == 0) {
Ext.Msg.Show(iGeneral.iSeleteNoneItem, iGeneral.iNote);
return false;
}
else (records.length != 0)
{
Ext.create('SMS.PostInfoWindow', {
edRecord: data,
edit: true,
title: iSMS_Post.iEditTitle,
grid: grid
}).show();
}
grid.getStore().reload();
},
//根据选中节点获取Id进行删除
onDeleteRange: function (btn) {
var grid = btn.up('RangePlanContentMg');
var rows = grid.getSelectionModel().getSelection()[0];
var pn = rows.parentNode;
Ext.MessageBox.confirm(iGeneral.iNote, '您确认要删除吗?', function (btn) {
if (btn == "yes") {
Ext.Ajax.request({
url: '../RangePlan/DeleteRangePlan',
params: { seqid: rows.get('SeqId') },
success: function (response) {
pn.removeChild(rows);
if (!pn.hasChildNodes()) {
pn.set('leaf', true);
}
grid.store.reload();
grid.getSelectionModel().selectNext(); //删除后,默认选择下一行.
Ext.custom.msg('提示:', '删除成功!', 2000);
},
failure: function (response) {
var errorMsg = Ext.decode(response.responseText).Error;
Ext.Msg.alert("Error", errorMsg);
}
});
}
});
},
///将前台页面的数据保存到后台
onSaveRange: function (btn) {
var grid = btn.up('RangePlanContentMg');
var store = grid.store.tree.root;
var dataList = new Array();
var j = 0;
dataList = getChildNotes(store);
function getChildNotes(node) {
for (var i = 0; i < node.childNodes.length; i++) {
var records = node.childNodes[i];
var data = {
"SeqId": records.data.SeqId,
"ProjectId": records.data.ProjectId,
"ParentSeqId": records.data.ParentSeqId,
"ItemId": records.data.ItemId,
"TaskName": records.data.TaskName,
"TaskDesc": records.data.TaskDesc,
"DestName": records.data.DestName,
"Measurement": records.data.Measurement,
"StartDate": records.data.StartDate,
"EndDate": records.data.EndDate,
"Status": records.data.Status,
"IsNew": records.data.IsNew,
"ApprovalStatus": records.data.ApprovalStatus,
"Remark": records.data.Remark,
"CreatedTime": records.data.CreatedTime,
"CreatedUserId": records.data.CreatedUserId,
"ApprovalRemak": records.data.ChangeApprovalRemark,
"ChangeApprovalRemark": records.data.ChangeApprovalRemark,
"Remark": records.data.Remark,
"leaf": true
};
dataList[j] = data;
j++;
getChildNotes(node.childNodes[i]);
}
return (dataList);
}
Ext.Ajax.request({
url: '../RangePlan/SaveRange',
params: {
rangeStr: Ext.encode(dataList)
},
method: 'POST',
success: function (response) {
var params = Ext.decode(response.responseText);
grid.store.reload();
Ext.custom.msg('提示:', '保存成功!', 2000);
},
failure: function (response) {
var errorMsg = Ext.decode(response.responseText).Error;
Ext.Msg.alert("Error", errorMsg);
}
});
},
Step3:前台数据的删除是直接删除数据库中数据,添加和修改操作可以批量进行,点击保存之后前台的数据一起在onSaveRange中传到Ctrollers中 :
/// <summary>
/// 通过前台选中SeqId删除选中数据项
/// </summary>
/// <returns></returns>
public JsonResult DeleteRangePlan(int seqid)
{
string errMsg;
var obj = new Modeltb_Plan_Range
{
//SPReturnType = AppEnum.SPReturnTypes.DataSet,
SeqId = seqid
};
Blltb_Plan_Range.Delete(obj, out errMsg);
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
/// <summary>
/// 保存前台修改和增加节点操作之后的数据
/// </summary>
/// <param name="rangeStr"></param>
/// <returns></returns>
public JsonResult SaveRange(string rangeStr)
{
string errMsg;
IList<Modeltb_Plan_Range> lstPosts = JSONUtil.JsonToObject(rangeStr, typeof(IList<Modeltb_Plan_Range>)) as IList<Modeltb_Plan_Range>;
foreach (Modeltb_Plan_Range item in lstPosts)
{
var obj = new Modeltb_Plan_Range
{
SeqId = item.SeqId,
ProjectId = item.ProjectId,
ItemId = item.ItemId,
ParentSeqId = item.ParentSeqId,
TaskName = item.TaskName,
TaskDesc = item.TaskDesc,
DestName = item.DestName,
Measurement = item.Measurement,
StartDate = item.StartDate,
EndDate = item.EndDate,
Status = item.Status,
IsNew =item.IsNew,
ApprovalStatus = item.ApprovalStatus,
Remark = item.Remark,
CreatedTime = item.CreatedTime,
CreatedUserId = item.CreatedUserId,
ApprovalRemak = item.ApprovalRemak,
ChangeRemark = item.ChangeRemark
};
if (item.SeqId != 0)
{
Blltb_Plan_Range.UpdateUnique(obj, out errMsg);
}
else {
Blltb_Plan_Range.InsertUnique(obj, out errMsg);
}
}
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
Step4:Controller中根据前台传过来的SeqId判断某条数据是修改还是添加的节点,然后调用不同的BLL层处理数据。
/// Insert Unique Data
/// </summary>
/// <param name="obj">Tabletb_Plan_Range Model</param>
/// <param name="errMsg">错误信息</param>
/// <returns>long</returns>
public static long InsertUnique(Modeltb_Plan_Range obj, out string errMsg)
{
object returnObj = MainDal.DoDal(obj, "Tabletb_Plan_Range", new List<object> { SPActionstb_Plan_Range.Unique, SPActionstb_Plan_Range.Insert }, out errMsg);
if (!string.IsNullOrEmpty(errMsg))
{
return -1;
}
return Convert.ToInt64(returnObj);
}
/// <summary>
/// Update Unique Data
/// </summary>
/// <param name="obj">Tabletb_Plan_Range Model</param>
/// <param name="errMsg">错误信息</param>
public static void UpdateUnique(Modeltb_Plan_Range obj, out string errMsg)
{
MainDal.DoDal(obj, "Tabletb_Plan_Range", new List<object> { SPActionstb_Plan_Range.Unique, SPActionstb_Plan_Range.Update }, out errMsg);
}
/// <summary>
/// Delete Data
/// </summary>
/// <param name="obj">Tabletb_Plan_Range Model</param>
/// <param name="errMsg">错误信息</param>
public static void Delete(Modeltb_Plan_Range obj, out string errMsg)
{
MainDal.DoDal(obj, "Tabletb_Plan_Range", new List<object> { SPActionstb_Plan_Range.Delete }, out errMsg);
}
提供了部分代码,这样一个前台树形表的批量操作就可以实现了。
- 基于MVC的前台ExtJs树型表格的批量数据操作实现
- ExtJs 表格的实现
- iOS开发总结之UITableView表格数据的批量操作
- ExtJS表格的操作:取选择项
- 基于Swift的iOS应用程序开发:使用表格显示并控制数据(三):批量处理表格数据
- 基于Spring3 MVC实现批量导出数据成Excel文件!
- Oracle批量操作(基于Mybatis的实现)
- 使用ExtJS5 GridPanel实现表格嵌套SubGrid(基于ExtJS MVC模式)
- 基于Ajax技术实现的数据表格控件
- 基于Ajax技术实现的下拉数据表格组件
- Json 批量表格/表单数据的处理
- 关于ExtJs前台Form获取后台的JSON数据
- Extjs前台数据传到java乱码问题的解决
- 批量插入数据(基于Mybatis的实现-Oracle)
- extjs 前台的开发工具
- 简单实现ExtJS的MVC模式
- iOS开发总结之UITableView表格数据的批量操作2
- excel表格数据的操作
- IOS线程数据篇12之Sqlite3其他属性:排列约束、外键约束、表连接
- michael kors australia gSPyc Ttlf UC71
- IoTivity Architecture (物联网架构)
- 把表二中缺少的列补全
- 漫步IOS--数组函数
- 基于MVC的前台ExtJs树型表格的批量数据操作实现
- sgu323 Aviamachinations
- sitemesh的使用
- 跟着实例学习java多线程1-为什么使用?
- git tag — 标签相关操作
- 作为一个iOS开发者,想知道作为一个Android开发者是一种怎样的体验
- VLC compile for Android
- ps 软件 各版本的下载地址
- 表格化顺序插入记忆单词方法