树结构:treegrid
前台:js
var url = "DATA/DsType.ashx?req_fun=";//数据层,(列表数据和删除)
$(function () {
$("#dg").treegrid({ //#dg为table的id
url: url + "getlist",
toolbar: "#dgtools", //标头,div的id
title: "实体类型维护",//名称
iconCls: "icon-standard-database",
fit: true,
pagination: false,
rownumbers: true,
singleSelect: true,
idField: 'DS_TYPE',//定义标识树节点的键名字段。必需。
treeField: 'TYPE_NAME',//定义树节点的字段。必需。
// sortName: 'TD_ID',
lines: true,//定义是否显示树线条。此处由于版本太低没发挥作用
columns: [[
{ field: 'TYPE_NAME', title: '类型名称', width: 150, sortable: true },
{ field: 'TYPE_CODE', title: '类型编码', width: 150, sortable: true },
{ field: 'TYPE_REMARK', title: '类型备注', width: 150, sortable: true },
]]
})
});
function typeAdd() {
ShowWindow("添加父结构类型", "DsTypeEdit.aspx?type=0&id=0", 400, 400, "icon-standard-database-add", successLoad);
}
function getRow() {
var row = $("#dg").treegrid("getSelected");//获取选中行
if (row)
return row;
else
return null;
}
function getRowId() {
if (getRow())
return getRow().DS_TYPE; //获取行id
}
function typeAddPID() {
var row = getRow();
if (!row) {
AlertInfo("请先选择父结构类型");
return;
}
ShowWindow("添加子父结构类型", "DsTypeEdit.aspx?type=1&id=" + getRowId(), 400, 400, "icon-standard-database-add", successLoad);
}
function typeEdit() {
var row = getRow();
if (!row) {
AlertInfo("请先选择数据项");
return;
}
ShowWindow("修改结构类型分类", "DsTypeEdit.aspx?type=2&id=" + getRowId(), 400, 400, "icon-standard-database-edit", successLoad);
}
function typeDel() {
var row = getRow();
if (!row) {
AlertInfo("请先选择数据项");
return;
}
var sel = $("#dg").treegrid("getSelected");//选中行
if (sel && sel.children && sel.children.length > 0) { //选中行的是否有子节点
AlertWarning("请先清空子父结构类型!");
return;
}
$.messager.confirm('删除确认', '确认删除此数据项吗?', function (r) {
//debugger;
if (r) {
AjaxPost(url + "del", { id: getRowId() }, function (res) {
if (res)
if (res == "true")
successLoad(true);
else
AlertInfo(res);
else
AlertInfo('删除失败');
});
}
});
}
function typeReload() { //刷新列表
$("#dg").treegrid("reload");
}
function successLoad(res) {
if (res)
typeReload();
}
注意问题:
(1)前台js: idField: '',
treeField: '',不能丢
在传递数据时,设type字段(即type=0时添加父节点;type=1时添加子节点;
type=2时修改)
(2)附加属性的意义:
pagination:设置为 true,则在数据网格(datagrid)底部显示分页工具栏。默认为false
rownumbers:设置为true,则显示代行的列,默认false
singleSelect:设置为true,则只允许选中一行,默认为false
(3)树结构逻辑关系:
父节点 pid(0)
子节点 id(注意:子节点的pid要等于上级父节点id)
(4)后台cs:
在页面载入时(修改时给赋值即根据传入id所查询的值)page_load()
在保存数据时,先创建一个没有实参的空的表实体对象(model层时实体层)
(如:Work.Model.PB_FORM_DS_TYPE_M parentmodel = new Work.Model.PB_FORM_DS_TYPE_M())
再创建一个表逻辑对象(logic为逻辑层)
(如: Work.Logic.PB_FORM_DS_TYPE_M bll = new Work.Logic.PB_FORM_DS_TYPE_M();)
分为三种情况,
第一种,type=0也就是添加父节点时让表实体对象的父id(pid)
等于0;
(如:parentmodel.TYPE_PID = 0;)
第二种,type=1也就是添加子结点时建立一个新的model实体对象,
然后给对象赋值,即根据id逻辑对象点方法获取此数据
(如:Work.Model.PB_FORM_DS_TYPE_M model = bll.GetEntity(id))
并且将此model的主键id值复制给刚开始建立的表实体对象(即第一步创建的没有实参的空parentmodel)
第三种,type=2也就是修改数据时,将逻辑对象根据id获取到的值赋给无实参的空parentmodel并判断当
此parentmodel不为空时,允许修改
最后,将共同体择出,即为将aspx中字段的text值付给无参的实例对象的属性,加以是否添加或修改成功的判断
(5)以下是一个treegrid的后台保存数据实例代码:
protected void lbtnSubmit_Click(object sender, EventArgs e)
{
try
{
int id = QueryInt("id");
Work.Model.PB_FORM_DS_TYPE_M parentmodel = new Work.Model.PB_FORM_DS_TYPE_M();
//decimal? = QueryDecimal("id", -1);
bool isEdit = false;
Work.Logic.PB_FORM_DS_TYPE_M bll = new Work.Logic.PB_FORM_DS_TYPE_M();
int addType = QueryInt("type");
if (addType == 0)
{
parentmodel.TYPE_PID = 0;
}
else if (addType == 1)
{
Work.Model.PB_FORM_DS_TYPE_M model = bll.GetEntity(id);
parentmodel.TYPE_PID = model.DS_TYPE;
}
else if (addType == 2)
{
parentmodel = bll.GetEntity(id);
if (parentmodel != null)
{
isEdit = true;
}
}
parentmodel.TYPE_NAME= this.txtNAME.Text;
parentmodel.TYPE_CODE = this.txtCODE.Text;
parentmodel.TYPE_REMARK = this.txtREMARK.Text;
bool exist = bll.ExistCode(parentmodel);
if (exist)
{
this.lblMsg.Text = "类型编码已存在";
return;
}
if (isEdit)
{
bool res = bll.EditEntity(parentmodel);
if (res)
CloseWindow(true);
else
{
this.lblMsg.Text = "修改失败";
}
}
else
{
bool res = bll.AddEntity(parentmodel);
if (res)
CloseWindow(true);
else
{
this.lblMsg.Text = "添加失败";
}
}
}
catch (Exception ex)
{
this.lblMsg.Text = ex.Message;
}
}
(6)以下是一个平常的后台保存数据实例代码:
protected void lbtnSubmit_Click(object sender, EventArgs e)
{
try
{
decimal? id = QueryDecimal("id", -1);
bool isEdit = false;
Work.Logic.PB_FORM_ORIGIN_TYPE bll = new Work.Logic.PB_FORM_ORIGIN_TYPE();
Work.Model.PB_FORM_ORIGIN_TYPE model = bll.GetEntity(id);
if (model == null)
model = new Work.Model.PB_FORM_ORIGIN_TYPE();
else
isEdit = true;
model.OT_NAME = this.txtNAME.Text;
model.OT_CODE = this.txtCODE.Text;
model.OT_KEY_WORD = this.txtKEY_WORD.Text;
model.OT_ASSEMBLY = this.txtASSEMBLY.Text;
model.OT_HANDLER = this.txtHANDLER.Text;
model.OT_REMARK = this.txtREMARK.Text;
bool exist = bll.ExistCode(model);
if (exist)
{
this.lblMsg.Text = "来源编码已存在";
return;
}
if (isEdit)
{
bool res = bll.EditEntity(model);
if (res)
CloseWindow(true);
else
this.lblMsg.Text = "修改失败";
}
else
{
bool res = bll.AddEntity(model);
if (res)
CloseWindow(true);
else
this.lblMsg.Text = "添加失败";
}
}
catch(Exception ex)
{
this.lblMsg.Text = ex.Message;
}
}
将(5)和(6)代码编写风格得出一个问题:
为什么要先创建一个空的实体对象而不是一般的直接传入实参?
因为treegrid保存数据的时候分了三种情况,在第二种和第三种情况中都有用到id这个参数
在前台添加子节点时要选择一个父节点也就意味着要传一个id(即上级父节点的主键id),而后
获取信息将选中的父节点的id赋给子节点的pid。在修改时传的id就是选中的这一行的id。
一般的,在后台的增加和修改时,直接创建带参的实体对象。因为一般前台增加时不用传id,
修改时才传id,所以在前台点击添加按钮时页面就是空的,而如果在treegrid后台一开始传了值
在添加子节点时就是有数据的,是不对的。(因为添加子节点时需要传父节点id啊)
前台:js
var url = "DATA/DsType.ashx?req_fun=";//数据层,(列表数据和删除)
$(function () {
$("#dg").treegrid({ //#dg为table的id
url: url + "getlist",
toolbar: "#dgtools", //标头,div的id
title: "实体类型维护",//名称
iconCls: "icon-standard-database",
fit: true,
pagination: false,
rownumbers: true,
singleSelect: true,
idField: 'DS_TYPE',//定义标识树节点的键名字段。必需。
treeField: 'TYPE_NAME',//定义树节点的字段。必需。
// sortName: 'TD_ID',
lines: true,//定义是否显示树线条。此处由于版本太低没发挥作用
columns: [[
{ field: 'TYPE_NAME', title: '类型名称', width: 150, sortable: true },
{ field: 'TYPE_CODE', title: '类型编码', width: 150, sortable: true },
{ field: 'TYPE_REMARK', title: '类型备注', width: 150, sortable: true },
]]
})
});
function typeAdd() {
ShowWindow("添加父结构类型", "DsTypeEdit.aspx?type=0&id=0", 400, 400, "icon-standard-database-add", successLoad);
}
function getRow() {
var row = $("#dg").treegrid("getSelected");//获取选中行
if (row)
return row;
else
return null;
}
function getRowId() {
if (getRow())
return getRow().DS_TYPE; //获取行id
}
function typeAddPID() {
var row = getRow();
if (!row) {
AlertInfo("请先选择父结构类型");
return;
}
ShowWindow("添加子父结构类型", "DsTypeEdit.aspx?type=1&id=" + getRowId(), 400, 400, "icon-standard-database-add", successLoad);
}
function typeEdit() {
var row = getRow();
if (!row) {
AlertInfo("请先选择数据项");
return;
}
ShowWindow("修改结构类型分类", "DsTypeEdit.aspx?type=2&id=" + getRowId(), 400, 400, "icon-standard-database-edit", successLoad);
}
function typeDel() {
var row = getRow();
if (!row) {
AlertInfo("请先选择数据项");
return;
}
var sel = $("#dg").treegrid("getSelected");//选中行
if (sel && sel.children && sel.children.length > 0) { //选中行的是否有子节点
AlertWarning("请先清空子父结构类型!");
return;
}
$.messager.confirm('删除确认', '确认删除此数据项吗?', function (r) {
//debugger;
if (r) {
AjaxPost(url + "del", { id: getRowId() }, function (res) {
if (res)
if (res == "true")
successLoad(true);
else
AlertInfo(res);
else
AlertInfo('删除失败');
});
}
});
}
function typeReload() { //刷新列表
$("#dg").treegrid("reload");
}
function successLoad(res) {
if (res)
typeReload();
}
注意问题:
(1)前台js: idField: '',
treeField: '',不能丢
在传递数据时,设type字段(即type=0时添加父节点;type=1时添加子节点;
type=2时修改)
(2)附加属性的意义:
pagination:设置为 true,则在数据网格(datagrid)底部显示分页工具栏。默认为false
rownumbers:设置为true,则显示代行的列,默认false
singleSelect:设置为true,则只允许选中一行,默认为false
(3)树结构逻辑关系:
父节点 pid(0)
子节点 id(注意:子节点的pid要等于上级父节点id)
(4)后台cs:
在页面载入时(修改时给赋值即根据传入id所查询的值)page_load()
在保存数据时,先创建一个没有实参的空的表实体对象(model层时实体层)
(如:Work.Model.PB_FORM_DS_TYPE_M parentmodel = new Work.Model.PB_FORM_DS_TYPE_M())
再创建一个表逻辑对象(logic为逻辑层)
(如: Work.Logic.PB_FORM_DS_TYPE_M bll = new Work.Logic.PB_FORM_DS_TYPE_M();)
分为三种情况,
第一种,type=0也就是添加父节点时让表实体对象的父id(pid)
等于0;
(如:parentmodel.TYPE_PID = 0;)
第二种,type=1也就是添加子结点时建立一个新的model实体对象,
然后给对象赋值,即根据id逻辑对象点方法获取此数据
(如:Work.Model.PB_FORM_DS_TYPE_M model = bll.GetEntity(id))
并且将此model的主键id值复制给刚开始建立的表实体对象(即第一步创建的没有实参的空parentmodel)
第三种,type=2也就是修改数据时,将逻辑对象根据id获取到的值赋给无实参的空parentmodel并判断当
此parentmodel不为空时,允许修改
最后,将共同体择出,即为将aspx中字段的text值付给无参的实例对象的属性,加以是否添加或修改成功的判断
(5)以下是一个treegrid的后台保存数据实例代码:
protected void lbtnSubmit_Click(object sender, EventArgs e)
{
try
{
int id = QueryInt("id");
Work.Model.PB_FORM_DS_TYPE_M parentmodel = new Work.Model.PB_FORM_DS_TYPE_M();
//decimal? = QueryDecimal("id", -1);
bool isEdit = false;
Work.Logic.PB_FORM_DS_TYPE_M bll = new Work.Logic.PB_FORM_DS_TYPE_M();
int addType = QueryInt("type");
if (addType == 0)
{
parentmodel.TYPE_PID = 0;
}
else if (addType == 1)
{
Work.Model.PB_FORM_DS_TYPE_M model = bll.GetEntity(id);
parentmodel.TYPE_PID = model.DS_TYPE;
}
else if (addType == 2)
{
parentmodel = bll.GetEntity(id);
if (parentmodel != null)
{
isEdit = true;
}
}
parentmodel.TYPE_NAME= this.txtNAME.Text;
parentmodel.TYPE_CODE = this.txtCODE.Text;
parentmodel.TYPE_REMARK = this.txtREMARK.Text;
bool exist = bll.ExistCode(parentmodel);
if (exist)
{
this.lblMsg.Text = "类型编码已存在";
return;
}
if (isEdit)
{
bool res = bll.EditEntity(parentmodel);
if (res)
CloseWindow(true);
else
{
this.lblMsg.Text = "修改失败";
}
}
else
{
bool res = bll.AddEntity(parentmodel);
if (res)
CloseWindow(true);
else
{
this.lblMsg.Text = "添加失败";
}
}
}
catch (Exception ex)
{
this.lblMsg.Text = ex.Message;
}
}
(6)以下是一个平常的后台保存数据实例代码:
protected void lbtnSubmit_Click(object sender, EventArgs e)
{
try
{
decimal? id = QueryDecimal("id", -1);
bool isEdit = false;
Work.Logic.PB_FORM_ORIGIN_TYPE bll = new Work.Logic.PB_FORM_ORIGIN_TYPE();
Work.Model.PB_FORM_ORIGIN_TYPE model = bll.GetEntity(id);
if (model == null)
model = new Work.Model.PB_FORM_ORIGIN_TYPE();
else
isEdit = true;
model.OT_NAME = this.txtNAME.Text;
model.OT_CODE = this.txtCODE.Text;
model.OT_KEY_WORD = this.txtKEY_WORD.Text;
model.OT_ASSEMBLY = this.txtASSEMBLY.Text;
model.OT_HANDLER = this.txtHANDLER.Text;
model.OT_REMARK = this.txtREMARK.Text;
bool exist = bll.ExistCode(model);
if (exist)
{
this.lblMsg.Text = "来源编码已存在";
return;
}
if (isEdit)
{
bool res = bll.EditEntity(model);
if (res)
CloseWindow(true);
else
this.lblMsg.Text = "修改失败";
}
else
{
bool res = bll.AddEntity(model);
if (res)
CloseWindow(true);
else
this.lblMsg.Text = "添加失败";
}
}
catch(Exception ex)
{
this.lblMsg.Text = ex.Message;
}
}
将(5)和(6)代码编写风格得出一个问题:
为什么要先创建一个空的实体对象而不是一般的直接传入实参?
因为treegrid保存数据的时候分了三种情况,在第二种和第三种情况中都有用到id这个参数
在前台添加子节点时要选择一个父节点也就意味着要传一个id(即上级父节点的主键id),而后
获取信息将选中的父节点的id赋给子节点的pid。在修改时传的id就是选中的这一行的id。
一般的,在后台的增加和修改时,直接创建带参的实体对象。因为一般前台增加时不用传id,
修改时才传id,所以在前台点击添加按钮时页面就是空的,而如果在treegrid后台一开始传了值
在添加子节点时就是有数据的,是不对的。(因为添加子节点时需要传父节点id啊)