近段时间,我所接手的一个项目是.Net MVC架构,控件大部分是使用Telerik的。由于项目中有很多数据是需要树形结构来展示的,之前项目是通过jstree控件来实现。jstree虽然扩展性很好,很多树的操作功能都可以实现,但是,要实现起来的代码比较多,也有些复杂。于是我就决定尝试采用Telerik的treeView来代替。
Telerik Extensions for ASP.NET MVC Demo : http://demos.telerik.com/aspnet-mvc/
看了Demo和相关帮助文档,觉得Telerik的TreeView的实现方便多了,写几行代码就可以完成一棵Tree,不过做着做着,才发现,TreeView虽然有展开(Expand(node))节点的方法,但并没有发现选中方法和双击事件。
The available client-side methods are: treeview.expand(node) - expands a treeview node. treeview.collapse(node) - collapses a treeview node. treeview.enable(node) - enables a treeview node. treeview.disable(node) - disables a treeview node. treeview.getItemText(node) - gets the text of a treeview node. treeview.getItemValue(node) - gets the value of a treeview node. If the value is not set, returns the node text. treeview.nodeCheck(node, isChecked) - checks/unchecks a treeview node that has a checkbox, depending on the value of isChecked. treeview.append(node, referenceNode) - appends a new node or moves an existing one to referenceNode. treeview.insertBefore(node, referenceNode) - inserts a new node or moves an existing one before referenceNode. treeview.insertAfter(node, referenceNode) - inserts a new node or moves an existing one after referenceNode.
至论坛上找也找不到,难道这就是Telerik控件的一些局限,百思不得其解。不过,后来我想了想,既然树都出来了,其他的事件或方法应该可以通过jquery来实现吧,毕竟Telerik的客户端也是通过Jquery集成的。于是一步步尝试,终于将这些问题解决了。
以下是实现的方法,望各位多指教!
- 展开
普通的展开很简单,如果你想展开现有树中的某个节点,只需要Expand(node); node为树中的Li(Jquery elements),也可以直接是jQuery selector,如:
var item = $("#OrgTlrTreeView").find(".t-input[name='itemValue'][value^='" + InputValue + "']").closest("li"); treeview.expand(item); 或 var treeview = $('#ProductsTreeView').data('tTreeView'); treeview.expand("li:first");
但是,一般的树都有默认打开多层级的节点功能,这个实现就有些难度。需要用到一层层展开,就要利用TreeView自身的OnDataBound事件,同时也要结合后台,将要展开的那级ID的所有父级ID也一并查出来,输出到页面。 以下我将以一个组织树来做例子。
组织树页面代码如下:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> <%= Html.Telerik().TreeView() .Name("OrgTlrTreeView") .DataBinding( dataBinding => { dataBinding.Ajax().Enabled(true).Select("GetOrgTlrTreeViewNodes", "Util"); } ).ClientEvents(events=>{ events.OnSelect("SelectOrgTlrTreeViewItem").OnLoad("changeHeigh").OnDataBound("OrgTlrTreeOnDataBound"); }) %> class='stander-button-div' id='createButtonDiv'> "button" value="确定" id="orgSelectSubmitBtn" οnclick="returnOrgTlrTreeValue(this);" /> "button" value="关闭" οnclick="CloseOrgTlrTreeWindow()" />
其中ViewData["DefaultExpandNodeIds"]是要展开的ID串,格式是“Children ID@Parent Id@Parent ID.....”
expandOrgTlrTreeLevel则是要展开的层级数。此页面中写出了OnDataBound("OrgTlrTreeOnDataBound"),但并未在此页面实现此事件方法的代码,OrgTlrTreeOnDataBound方法在调用页面实现,具体如下:
function OrgTlrTreeOnDataBound() { var treeview = $('#OrgTlrTreeView').data('tTreeView'); if (expandOrgTlrTreeLevel == 0) { //Selete Node selectNodeArray[0] var tempSelectId = selectOrgTlrTreeNodeArray[0]; if (tempSelectId != "" && tempSelectId != null) { var selectSpan = $("#OrgTlrTreeView").find(".t-input[name='itemValue'][value^='" + tempSelectId + "']").prevUntil("t-in")[0]; $(selectSpan).attr("class", "t-in t-state-selected"); } //Reset Level expandOrgTlrTreeLevel = selectOrgTlrTreeNodeArray.length - 1; } else { var item = $("#OrgTlrTreeView").find(".t-input[name='itemValue'][value^='" + selectOrgTlrTreeNodeArray[expandOrgTlrTreeLevel] + "']").closest("li"); treeview.expand(item); expandOrgTlrTreeLevel--; } }
if (expandOrgTlrTreeLevel == 0)里是实现选中功能的,下面会讲,先看else部分代码。else里是通过所给的层级ID来查找对应的LI 元素,通过expand(item)方法将其展开,因为展开又会触发TreeView的OnDataBound事件,所以,你所传入的节点值ViewData["DefaultExpandNodeIds"]都会一一展开(当然,你的顺序必须符合树的层级顺序才有用)。这样默认展开多级节点的功能就实现了。
- 默认选中
默认选中这个有些坑爹,其实选中表面上只是样式有所变化而已。你打开一个TreeView,选中某一数据项,就会发现,选中标签中的只是多了一个类名而已(class="t-in t-state-selected"),所以我们只需要在目标节点改变Span的Class值得就可以了。如在上述方法(OrgTlrTreeOnDataBound)图中的if (expandOrgTlrTreeLevel == 0)代码中就是实现这个功能。当然,这只是一个表面上的选中,内在的数据值中,记得也要作相应的改变。如将默认选中节点的值ID,赋给Hidden。
- 双击
对于TreeView双击事件,Telerik TreeView中对节点的双击事件默认是实现展开或折叠节点的动作。不过,如果这个树结构是作为一个选择控件,将这个双击事件变成确定选择的操作,会变得更加合适。
虽然TreeView不提供双击事件,但可以通过JQuery事件来进行绑定。代码如下:
$(document).ready(function () { //类型双击事件 $("#OrgTlrTreeView .t-in").live("dblclick", function () { var ee = new Object(); ee.item = $(this).closest("li"); SelectOrgTlrTreeViewItem(ee); returnOrgTlrTreeValue(document.getElementById("orgSelectSubmitBtn")); }); });
$("#OrgTlrTreeView .t-in")就是树中各个节点的文字标签Span,将这些Span统统绑定上"dblclick"事件,然后将节点的选择实现代码写入其中就OK了。
returnOrgTlrTreeValue(obj)是确定按钮的点击方法,代码在调用页面实现,主要是实现将树中的选择结果赋给Hidden控件。而所传入的Obj为确定按钮的DOM,可以通过这个Dom来找到父元素的ID,其作用是用来区分单页多个相同PartialView(用于复用控件对话框)的引用。
好了,先写这么多。
希望上述能给各位网友带来帮助。望多指教!