在ASP.NET AJAX中使用自定义ViewManager局部更新数据

有时你不想用updatepanel,因为每次发出一个请求时,它会回发许多你不必用到的信息。当然updatepanel是强大的,易于使用的,但它不是一直都是一种高效的方法。你可能想不使用viewstate和postback,而要获得一个页面传递过来的数据结果,而且你想这个网页能被你驱动和使用最少的数据回发。

下面要讲的内容来自于Scott Guthries ViewManager 。最近我的一个想法促使我在客户端做许多的事情,也许我能不使用updatepanel。我之前已经做了许多通用的ViewManager,基本上就是允许你更容易地设置控件的属性并让你在执行和更新它之前设置它的任何属性。不要责备我之前写的文章,我发现我写的viewmanager更容易使用。所以我才分享它。

Data Control:
你需要创建一个用来更新数据页面的用户控件。就我来说,我会给这个控件一些属性,以至于你可以设置当前页和页面大小。我会把数据更新到一个listview里面,我的数据来自于一个数据库,我会使用LINQ to SQL来访问数据库。

<% @ Control Language = " C# "  AutoEventWireup = " true "  CodeBehind = " Data.ascx.cs "  Inherits = " NoUpdatePanels.Data "   EnableViewState = " false "   %>
< asp:ListView ID = " lvData "  runat = " server "  ItemPlaceholderID = " plcItem " >            
    
< LayoutTemplate >
        
< br  />< br  />
        
< asp:PlaceHolder ID = " plcItem "  runat = " server " ></ asp:PlaceHolder >
    
</ LayoutTemplate >
    
< ItemTemplate >
        Name: 
<% # Eval( " Name " %>
        
< hr  />
    
</ ItemTemplate >
</ asp:ListView >

using  System;
using  System.Collections;
using  System.Configuration;
using  System.Data;
using  System.Linq;
using  System.Web;
using  System.Web.Security;
using  System.Web.UI;
using  System.Web.UI.HtmlControls;
using  System.Web.UI.WebControls;
using  System.Web.UI.WebControls.WebParts;
using  System.Xml.Linq;

namespace  NoUpdatePanels {
    
public   partial   class  Data : System.Web.UI.UserControl {

        
#region  Properties

        
public   int  CurrentPage {  get set ; }
        
public   int  PageSize {  get set ; }

        
#endregion

        
#region  Constructors/Load

        
//  Constructor, just init properties
         public  Data() {
            
this .CurrentPage  =   0 ;
            
this .PageSize  =   5 ;
        }

        
protected   void  Page_Load( object  sender, EventArgs e) {
            TestDataContext db 
=   new  TestDataContext();

            var query 
=  (from p  in  db.Persons
                         select p).Skip(CurrentPage 
*  PageSize).Take(PageSize);

            lvData.DataSource 
=  query;
            lvData.DataBind();
        }

        
#endregion

    }
}

大体上,我所做的是根据当前页和页的大小,获得页面数据,并绑定到listview上。当然这个控件的viewstate也被我停用了。

The Page:
hosting网页是用来获得控件更新后的数据。所有的工作都在客户端使用web service完成。但在这里我没有用web service(懒一点)而是在我的网页上用了一个静态方法,然后我在ScriptManager里设置EnablePageMethods=true。就是这样了,大体上网页要做的事是使用网页的方法来获得网页的数据。这个网页方法接受一个current page参数,并根据数据控件设置的currentpage属性生成一个viewmanager实例,然后更新控件,返回数据。

这个网页使用了JavaScript来调用方法。并把结果放到一个div里。这这里有一点要注意的,脚本在网页结束的时候不会停下来,也不会进行真正的错误检查,它只是我的一种想法的原型。下面是html代码和后台代码:

<% @ Page Language = " C# "  AutoEventWireup = " true "  CodeBehind = " Default.aspx.cs "  Inherits = " NoUpdatePanels._Default "   %>

<% @ Register src = " Data.ascx "  tagname = " Data "  tagprefix = " uc1 "   %>

<! DOCTYPE html PUBLIC  " -//W3C//DTD XHTML 1.0 Transitional//EN "   " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >

< html xmlns = " http://www.w3.org/1999/xhtml "   >
< head runat = " server " >
    
< title > Client Side Data Loading </ title >    
</ head >
< body >
    
< form id = " form1 "  runat = " server " >
        
< asp:ScriptManager ID = " ScriptManager1 "  runat = " server "  EnablePageMethods = " true " ></ asp:ScriptManager >

        
< a href = " http://weblogs.asp.net/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost# "  onclick = " PreviousPage(); " > Previous  & lt; </ a >   -   < a href = " http://weblogs.asp.net/controlpanel/blogs/posteditor.aspx?SelectedNavItem=NewPost# "  onclick = " NextPage(); " > Next  & gt; </ a >
        
< div id = " contentRegion " >        
            Loading
        
</ div >

    
</ form >
    
< script type = " text/javascript " >
        var currentPage 
=   0 ;       
       
        function LoadPage(page) {
            PageMethods.GetDataPage(page, function(result) {
                
//  We loaded our data populate our div.               
                document.getElementById( " contentRegion " ).innerHTML  =  result;
            },
            function(error) {
                alert(error.get_message());
            });
        }
       
        function PreviousPage() {
            currentPage
-- ;
            LoadPage(currentPage);   
        }
       
        function NextPage() {
            currentPage
++ ;
            LoadPage(currentPage);
        }
       
        
//  Add our load event handler
        Sys.Application.add_load(LoadPage);
    
</ script >
</ body >
</ html >

using  System;
using  System.Collections;
using  System.Configuration;
using  System.Data;
using  System.Linq;
using  System.Web;
using  System.Web.Security;
using  System.Web.UI;
using  System.Web.UI.HtmlControls;
using  System.Web.UI.WebControls;
using  System.Web.UI.WebControls.WebParts;
using  System.Xml.Linq;
using  System.Web.Services;

namespace  NoUpdatePanels {
    
public   partial   class  _Default : System.Web.UI.Page {

        [WebMethod()]
        
public   static   string  GetDataPage( int  page) {

            
//  Create an instance of our viewmanager.
            ViewManager < Data >  man  =   new  ViewManager < Data > ( " ~/Data.ascx " );

            
//  Set the current page property.
            man.Control.CurrentPage  =  page;

            
//  Return the rendered control.
             return  man.Render();
        }

    }
}

The ViewManager:
这是通用viewmanager,它实际上是负责更新控件的工作。

using  System;
using  System.Data;
using  System.Configuration;
using  System.Linq;
using  System.Web;
using  System.Web.Security;
using  System.Web.UI;
using  System.Web.UI.HtmlControls;
using  System.Web.UI.WebControls;
using  System.Web.UI.WebControls.WebParts;
using  System.Xml.Linq;
using  System.Text;
using  System.IO;

namespace  NoUpdatePanels {

    
///   <summary>
    
///  A generic user control rendering helper, basically you initialise the view manager and
    
///  call render to render that control, but the benifit of this version is you can access the control
    
///  the view manager is rendering and can set custom properties etc.
    
///   </summary>
    
///   <typeparam name="T"> The type of the control you are rendering </typeparam>
     public   class  ViewManager < T >   where  T : Control {

        
#region  Properties

        
private  T _control  =   default (T);

        
///   <summary>
        
///  Gives you access to the control you are rendering allows
        
///  you to set custom properties etc.
        
///   </summary>
         public  T Control {
            
get  {
                
return  _control;
            }
        }

        
//  Used as a placeholder page to render the control on.
         private  Page _holder  =   null ;

        
#endregion

        
#region  Constructor

        
///   <summary>
        
///  Default constructor for this view manager, pass in the path for the control
        
///  that this view manager is render.
        
///   </summary>
        
///   <param name="inPath"></param>
         public  ViewManager( string  path) {
            
// Init the holder page
            _holder  =   new  Page();

            
//  Create an instance of our control
            _control  =  (T)_holder.LoadControl(path);

            
//  Add it to our holder page.
            _holder.Controls.Add(_control);
        }

        
#endregion

        
#region  Rendering

        
///   <summary>
        
///  Renders the current control.
        
///   </summary>
        
///   <returns></returns>
         public   string  Render() {
            StringWriter sw 
=   new  StringWriter();

            
//  Execute the page capturing the output in the stringwriter.
            HttpContext.Current.Server.Execute(_holder, sw,  false );

            
//  Return the output.
             return  sw.ToString();
        }

        
#endregion

    }

}

 

转载于:https://www.cnblogs.com/liyou-blog/archive/2009/09/28/fggf.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值