返回首页
当前位置: 主页 > 网络编程 > .Net实例教程 >

Sys.UI.Data.DataNavigator与Sys.UI.Data.SortBehavior

时间:2014-02-26 14:49来源:知行网www.zhixing123.cn 编辑:麦田守望者

这次我想讨论与分析的内容是Sys.UI.Data.DataNavigator与Sys.UI.Data.SortBehavior。在这之前,可能感兴趣的朋友们需要先了解一下Atlas Client Script中Data Control的使用方法。可以先学习一些别的文章,例如官方说明《Start > Quickstart Developer Tasks > Performing Data Access》,而Dflying兄的Atlas介绍系列也实属精品。

Sys.UI.Data.DataNavigator和Sys.UI.Data.SortBehavior的作用都是配合DataView进行数据操作:一个操作分页功能,一个操作排序功能。事实上这两个类都是属于辅助类,它们的功能是更加方便了开发,而提供的额外功能却不多。

Sys.UI.Data.SortBehavior使用了DataView的自带的属性与方法为DataView的内容进行了排序。当一个SortBehavior被应用到了一个控件时,它会根据控件的点击来决定DataView的排序顺序(在ASC和SESC之间切换),并且根据当前的排序顺序为control应用不同的样式(sortAscendingCssClass或sortDescendingCssClass)。如果没有这个控件,我们可能就需要配合使用setProperty,invokeMethod进行较为复杂的应用了。换个角度说,如果某个功能比较复杂并且需要复用的话,我们可以像SortBehavior一样封装起一系列操作。

Atlas中的控件设计并不随意,而是实实在在地“有用”。

但是,与Sys.UI.Data.SortBehavior相比,Sys.UI.Data.DataNavigator就有些古怪了。

Sys.UI.Data.DataNavigator提供了DataView的分页功能,不过无论是上一页也好,最后一页也罢,它的实现其实只是简单的使用了DataView的一个函数:set_pageIndex。配合get_pageIndex获得当前的页数,实现这些功能自不必说。不过非常有趣(或者继续使用上面的说法:古怪)的是触发DataNavigator那些功能的方式。DataNavigator没有提供任何的方法来触发它的那些操作,它的那些操作都是定义在DataNavigator的onBubbleEvent方法中。它的onBubbleEvent里判断了Sys.UI.Button对象传给它的Sys.UI.CommandEventArgs对象中commandName属性的值,然后进行不同的操作。

onBubbleEvent是我觉得在Atlas中比较奇特的玩意儿之一。它是定义在Sys.UI.Control类中的虚函数,直接或间接继承Sys.UI.Control的类可以对它进行重载。不过在代码中并不会调用onBubbleEvent,如果需要bubble event,那么就需要调用定义在Sys.UI.Control类中的raiseBubbleEvent方法。熟悉ASP.NET Server Control开发的朋友们应该可以发现这和ASP.NET中System.Web.UI.Control的OnBubbleEvent和RaiseBubbleEvent非常的类似,只可惜在Javascript中无法定义protected方法,只得把它们暴露在外了。

可以看出Atlas有多么深厚的ASP.NET背景。与ASP.NET一样,Atlas中的raiseBubbleEvent方法也不是个虚函数,它的定义无法改变,我们来看一下它的代码:

this.raiseBubbleEvent = function(source, args) {
    
var currentTarget = this.get_parent();
    
while (currentTarget) {
        
if (currentTarget.onBubbleEvent(source, args)) {
            
return;
        }
        currentTarget 
= currentTarget.get_parent();
    }
}

从当前控件开始,调用onBubbleEvent方法,如果返回false,则继续向parent传递,这样event就被bubble了。这是很标准的raiseBubbleEvent功能实现。

但是事情没有这么简单。在raiseBubbleEvent中可以看出,代码是通过parent属性获得上一级控件的引用。parent也是个无法重载的非虚成员,它定义在Sys.UI.Control中。不知道为什么,在官方的Client Library中缺少这个属性。我们来看一下它的实现。

this.get_parent = function() {
    
if (_parent) {
        
return _parent;
    }
    
else {
        
var parentElement = this.element.parentNode;
        
while (parentElement) {
            
if (parentElement.control) {
                
return parentElement.control;
            }
            parentElement 
= parentElement.parentNode;
        }
        
return null;
    }
}

可以看出这个属性的逻辑,如果曾经定义了parent,那么就返回parent引用,如果没有的话,那么就沿着DOM向父级元素找,找到第一个具有Atlas控件对象的元素。因此可以发现,parent并不需要被强制定义。为了证实这一点,在这里我借用一下Dflying兄在其文章《使用ASP.NET Atlas PageNavigator控件实现客户端分页导航》中编写的例子,我将对其进行简单的修改。

在Dflying兄的例子里有如下的定义:
 

<!-- PageNavigator -->
<div id="pageNavigator">
    
<input type="button" id="btnFirstPage" value="&lt;&lt;" />
    
<input type="button" id="btnPrevPage" value="&lt;" />
    
<span id="lblPageNumber"></span> / <span id="lblPageCount"></span>
    
<input type="button" id="btnNextPage" value="&gt;" />
    
<input type="button" id="btnLastPage" value="&gt;&gt;" />
</div>

<script type="text/xml-script">
    
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
        
<components>
            ...
            
<dataNavigator id="pageNavigator" dataView="view" />
            
<button id="btnFirstPage" parent="pageNavigator" command="FirstPage" />
            
<button id="btnPrevPage" parent="pageNavigator" command="PreviousPage">
                ...
            
</button>
            
<button id="btnNextPage" parent="pageNavigator" command="NextPage">
                ...
            
</button>
            
<button id="btnLastPage" parent="pageNavigator" command="LastPage" />
            ...
        
</components>
    
</page>
</script>

在这里,dataNavigator是那些<input type="button" />的父结点,而在Atlas Xml Scripts中也为每个button指定了自身的parent属性。我们先尝试着去除上方HTML定义的元素父子关系,保留下方Script不变:

<div id="pageNavigator"></div>
    
<input type="button" id="btnFirstPage" value="&lt;&lt;" />
    
<input type="button" id="btnPrevPage" value="&lt;" />
    
<span id="lblPageNumber"></span> / <span id="lblPageCount"></span>
    
<input type="button" id="btnNextPage" value="&gt;" />
    
<input type="button" id="btnLastPage" value="&gt;&gt;" />
</div>

运行,一切正常。可以发现作为dataNavigator的元素无需为那些button的父结点。

接着,我们保留HTML元素的父子关系,在下方撤销在Atlas Scripts中的parent定义,如下:

<script type="text/xml-script">
    
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
        
<components>
            ...
            
<dataNavigator id="pageNavigator" dataView="view" />
            
<button id="btnFirstPage" parent="pageNavigator" command="FirstPage" />
            
<button id="btnPrevPage" parent="pageNavigator" command="PreviousPage">
                ...
            
</button>
            
<button id="btnNextPage" parent="pageNavigator" command="NextPage">
                ...
            
</button>
            
<button id="btnLastPage" parent="pageNavigator" command="LastPage" />
            ...
        
</components>
    
</page>
</script>

运行,依旧一切正常。可见,Atlas会自动在DOM树中寻找作为dataNavigator的control。感兴趣的朋友也可以尝试着将上述两者都去除,这样分页功能就会失效了。

------分隔线----------------------------
标签(Tag):C# C#实例教程 c#基础教程 C#源代码 c#技巧
------分隔线----------------------------
推荐内容
猜你感兴趣