EasyUI - datagrid属性idField详解

​idField​​​在​​treegrid​​中的是一个必选的属性,在​​datagrid​​中是一个可选的属性。

也许有人为了方便使用​​getRowIndex​​​会在​​datagrid​​​中设置​​idField​​​属性,如果不注意这个属性,那么在调用​​getSelected​​​或者​​getChecked​​方法时会引起更多莫名其妙的问题。

这篇博客就是讲​​datagrid​​​中的​​idField​​​对​​getSelected​​​和​​getChecked​​方法相关方法的影响。

因为​​selected​​​和​​checked​​​情况类似,下面就以​​selected​​的情况来说明。

在选中一行的时候

执行的部分关键代码如下:

if (opts.idField) {
_5cf(_6b9.selectedRows, opts.idField, row);
}
opts.finder.getTr(_6b6, _6b7).addClass("datagrid-row-selected");
opts.onSelect.apply(_6b6, _5d0(_6b6, [_6b7, row]));

这里的​​_6b9​​​是​​datagrid​​​的​​data-datagrid​​属性,获取方法为:

//使用jquery获取
$('#datagridId').data('datagrid');
//在easyui源码中使用下面方法获取
$.data(_6a7, "datagrid");

这个对象的一级属性如下图:

EasyUI - datagrid属性idField详解_idField

注意看这里的​​checkedRows​​​和​​selectedRows​​属性。

继续看第一段代码,当​​if (opts.idField)​​​存在​​idField​​​属性的时候,会调用​​_5cf​​方法:

function _5cf(a, o, r)
for (var i = 0, len = a.length; i < len; i++) {
if (a[i][o] == r[o]) {
return;
}
}
a.push(r);
};

这个方法就是当新选择的值和​​selectedRows​​​中已有的​​idField​​​值都不相同的时候,放到​​selectedRows​​​中。通过​​idField​​避免重复!

当没有设置​​idField​​​属性的时候,就没有​​selectedRows​​的事,只是调用下面的代码:

opts.finder.getTr(_6b6, _6b7).addClass("datagrid-row-selected");

这个代码就是给当前点击的行添加一个选中的样式,如下图:

EasyUI - datagrid属性idField详解_i++_02

通过上面代码我们应该已经了解选中一行的过程。

下面我们看当取消选中行时是如何处理的

关键代码如下:

opts.finder.getTr(_6bb, _6bc).removeClass("datagrid-row-selected");
if

看过前面的再看这里就容易很多了,首先​​removeClass​​去掉选中的样式。

然后如果有​​idField​​​属性,执行​​_5cd​​方法:

function _5cd(a, o, id)
if (typeof o == "string") {
for (var i = 0, len = a.length; i < len; i++) {
if (a[i][o] == id) {
a.splice(i, 1);
return;
}
}
} else {
var _5ce = _5cc(a, o);
if (_5ce != -1) {
a.splice(_5ce, 1);
}
}
};

如果取消的列在​​selectedRows​​中,就会从中移除(这里的else一般不会出现,不需要重视这里)。

到这儿我们就了解了​​selectedRows​​增加和删除的情况。

注意1

这里要强调的是​selectedRows中的值只能通过取消选择,或者​unselectAll​取消 【当前页】 的选择,即使重新加载数据,或者清空数据,都不会影响​selectedRows​中的值。想要取消全部选择怎么办?你可以使用​clearSelections​方法:

$('#id').datagrid('clearSelections');

取消全部选择,这个方法和当前显示的数据或者加载过的数据无关。这个方法如下:

clearSelections: function (jq)
return jq.each(function ()
var _76d = $.data(this, "datagrid");
var _76e = _76d.selectedRows;
var _76f = _76d.checkedRows;
_76e.splice(0, _76e.length);
_6ba(this);
if (_76d.options.checkOnSelect) {
_76f.splice(0, _76f.length);
}
});
}

获取​​selectedRows​​​后,通过​​_76e.splice(0, _76e.length);​​​清空​​selectedRows​​​,这一步已经达到我们的基本目标了,然后是调用​​_6ba(this);​​​,这一步是取消当前页的选中状态(就是​​unselectAll​​​方法)。如果​​checkOnSelect=true​​​,在​​_6ba​​​方法中也有这个判断,会取消复选框选中状态,在这里会清空​​checkedRows​​的值。

当你只想获取当前页的选择项时,最好的解决方法就是不设置idField属性。否则就要自己处理好调用​clearSelections​的时机。

注意2

同时你也应该了解,合理的使用idField还可以实现翻页选择(checkbox一样),这种情况下,你的​datagrid​能记住每一页的选中情况,而且通过​getSelections​(或​getChecked​)来获取所有页中选中的行。

下面我们看当调用​​getSelected​​方法时,是如何处理的

这个方法的定义如下:

getSelected: function (jq)
var rows = _6a6(jq[0]);
return rows.length > 0 ? rows[0] : null;
}

获取​​rows​​​后返回第一个或者​​null​​​。在看​​_6a6​​方法:

function _6a6(_6a7)
var _6a8 = $.data(_6a7, "datagrid");
var opts = _6a8.options;
var data = _6a8.data;
if (opts.idField) {
return _6a8.selectedRows;
} else {
var rows = [];
opts.finder.getTr(_6a7, "", "selected", 2).each(function ()
rows.push(opts.finder.getRow(_6a7, $(this)));
});
return

当我们设置​​idField​​​时,直接将​​selectedRows​​​返回了。
如果没有设置​​​idField​​​,就会使用​​else​​​中的方法,获取所有​​selected​​​的元素,然后一个个循环,放到​​rows​​​数组中返回。
从上面这两种处理方式来看,显然是有​​​idField​​的时候效率更高(else效率也不低)。

其他和​​selected​​有关的方法,最终调用执行的都是上面提到的这些方法。这里不一一介绍了。

​idField​​​最有用的地方​​getRowIndex​

​getRowIndex​​​需要一个参数,​​row​​​或者​​id​​​的值,使用​​id​​​的前提就是设置​​idField​​。

下面是​​getRowIndex​​方法:

function _6a3(_6a4, row)
var _6a5 = $.data(_6a4, "datagrid");
var opts = _6a5.options;
var rows = _6a5.data.rows;
if (typeof row == "object") {
return _5cc(rows, row);
} else {
for (var i = 0; i < rows.length; i++) {
if (rows[i][opts.idField] == row) {
return i;
}
}
return -1;
}
};

当使用​​row​​​参数时,满足​​typeof row == "object"​​​,之后调用​​_5cc​​​方法,和所有的​​rows​​一一比较返回。

另外就是使用​​idField​​​方式,​​_6a5.data.rows​​​包含了当前页的所有行。对所有行循环,比较​​idField​​​相同的值,直接返回行号,这种方式使用也方便,因为我们业务中很容易能获取​​id​​​的值,而不容易得到一行​​row​​。

最后

官方文档中对​​idField​​的介绍只有下面的这些:

idField - string - Indicate which field is an identity field.

只有通过查看源码你才能发现原来​​idField​​竟然起了这么多的作用,这个属性隐藏的含义太多,不注意就会遇到“莫名其妙”的问题。

希望通过本文能让你对​​datagrid​​​中的​​idField​​有所了解。