• ajax数据加载经验分享


        好久没写篇像样的随笔了,昨天晚上看了老赵的随笔,又由于这段时间这方面技术用的比较多,可能大家已经在用了.这里且与大家分享.


    一.纯数据输出

    1.早在看ActionScript的时候便接触到了这种写法,直到ajax很火的时候,才知道这种格式叫json.

    json数据格式是供前端javascript进行操作的暂时性的数据格式,由于javascript语言的原因,访问json数据非常方便,灵活.本来由后端负责产生Ui的,现在全部由javascript操作dom来产生.避免重复,请大家参考此文JSON简介,同时推荐看看IBM的
    掌握 Ajax系列.

    为了产生json格式的数据,asp.net ajax框架提供了一个JavaScriptSerializer类用于将数据转换成json.

    分析下此做法的优点与缺点

    优点:
    1.后台传输数据量会比较小,减轻服务器压力
    2.前端操作非常灵活,可以做很多事情
    3.适用于交互性比较强的应用.
    缺点:
    1.必须要操作dom才能产生ui,无法与美工配合工作,需要熟悉javascript和dom的人来参与
    2.大数据量下,前端javascript对json数据的解析和dom的生成会明显减慢.
    豪无疑问的,直接产生html比解析要速度来的快.这是一点,要是在后端直接输出html的话,可能会由于产生的字符串太多,直接拖垮IE,挂掉.
    我想唯一的做法就是尽量避免大数据量,这便要看大家的创意了,还有就是输出json,然后对json分批操作解析,这样也会有所缓解.
    3.灵活的同时,降低了通用性(我有一个需求,某一天我用ajax用到我不想用了,我想回到传统的网页上去,啊噢,这种开发模式做不到)
    4.前端开发人员必须了解json数据格式

    二.与Ui一起输出

    这是我们一贯的做法,如asp.net ajax中的UpdatePanel,其会去后端请求其Panel中所有的UI,然后返回给前端,前端不需要解析,直接得到数据输出便可.

    分析下此做法的优点与缺点

    优点:
    1.可以与美工配合,避免动态产生dom的错误
    2.前端开发人员不再需要了解后端传回什么数据格式,直接输出
    3.复用性比较强,可以同时满足ajax和传统网页的浏览模式

    缺点:
    1.大大降低了数据的交互性,前端有时候无法得到想要的对象,只能依赖于后端产生的html数据.
    2.后端数据传输量稍微变大,不过影响不大.(相对而言,后端把对象解析成json格式需要时间,前端解析json数据也是需要时间的,主要的速度瓶颈还是在数据库连接访问这里)

    三.选择你想要的开发模式

    上面两种模式没有谁好谁不好之说,追求效率的人可能会选第一种,这种模式与语言无端,可以套用在php,jsp,asp,都可以.
    第二种开发模式比较适合asp.net,为什么呢?因为asp.net本身便存在着控件这一用法,而且效率并不低.

    大家可以先看看老赵这篇技巧:使用User Control做HTML生成

    四.我的做法

    1.我有一个白老鼠程序,自己写的blog程序,我会在其上面应用一些新技术,然后思考一些问题.
    初期阶段,我用ajax去加载UserControl中产生的html,开始感觉很好.后来我又想做成传统的网页形式,去掉ajax的加载方式,所以,我需要这么写(很高兴,终于看到代码了)
    <%@ Page ContentType="text/html" Language="C#" EnableViewState="true" MasterPageFile="~/Templete.Master" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="NLBS._default" Title="无标题页" %>
    <%@ Register Src="Control/content.ascx" TagName="content" TagPrefix="uc11" %>

    <asp:Content ID="Content1" runat="server" contentplaceholderid="ContentPlaceHolder1">

    <uc11:content ID="content" runat="server" />
       
    </asp:Content>
    content用户控件,用于显示文章列表.大家可以看看我的白老鼠程序http://www.clingingboy.cn
    然后我做着做着...看到别人的blog有ajax应用,那个酷啊,而且我的虚拟主机便宜,访问数据速度慢.我又想把它换成ajax模式爽一把(我的天),或者说我想随意变换数据的加载模式.这种模式采用json数据格式的话根本无法满足需求,修改太大.怎么办怎么办?

    由于本人偷偷的看了下ComponentArt的CallBack控件的源码(其实很早就看了),所以本人也仿照其做了一个自己的CallBack控件.我需要一个容器放content用户控件,然后再异步加载.现在现实的问题,这个页面便是content用户控件的容器.我们通过改变url参数来加载不同数据.(控件呈现是在Render方法中实现)
    看下面代码.现在你可以访问诸如http://www.clingingboy.cn/default.aspx?singleArticle_param=true&ID=70  这样的url来获取content数据

            protected override void Render(HtmlTextWriter writer)
            
    {
                
    //得到一个querystring参数
                string[] requestParams = this.GetCallbackParameters();
                
                
    if (requestParams != null && requestParams.Length > 0)
                
    {
                    
    //输出控件数据
                    this.HandleCallback(requestParams);
                    
    return;
                }

                
                
    base.Render(writer);
            }

         
    private void HandleCallback(string[] arParams)
            
    {
                
    try
                
    {
                    
    //try render the HtmlTextWriter
                    
                    StringWriter oStringWriter 
    = new StringWriter();
                    HtmlTextWriter oWriter 
    = new HtmlTextWriter(oStringWriter, string.Empty);

                    CallBackEventArgs oArgs 
    = new CallBackEventArgs(oWriter);
                    oArgs.Parameter 
    = arParams[0];
                    oArgs.Parameters 
    = arParams;

                    
    this.OnCallback(oArgs);

                    oWriter.Close();

                    Context.Response.Clear();
                    
                    Context.Response.Write(oStringWriter.ToString().Trim());

                }

                
    catch (Exception ex)
                
    {
                    
    //render ther error
                    this.HandleCallbackError(ex);
                }


                
    try
                
    {
                    Context.Response.End();
                }

                
    catch { }
            }



    小心:如果此时,你在本页面来请求content用户控件,呈现出来的会是2个content控件的ui.所以我们需要另建一个空白页面。使用此模式你不旦可以加载用户控件,同时也可以加载asp.net的内置控件。

    2.ajax数据加载与传统url同在

    我要访问一篇:博客园的一篇随笔,如http://www.cnblogs.com/JeffreyZhao/archive/2007/12/30/usercontrol_as_an_template.html,那在ajax模式下,我们不是要去掉此url,换成javascript的一个数据请求函数?我们可以用preventDefault()方法把链接给屏蔽掉,或者用stopPropagation()方法把事件给阻截下来.(上面两个方法都是firefox下的方法,ie也有此功能方法,asp.net ajax框架进行了封装)

    三.ajax加载用户控件
    在MVC中的应用

    相信有部分人已经在开始研究asp.net ajax了,请看此文Ajax with the ASP.NET MVC Framework。作者写了一个Script#,所以其前端javascript代码也是通过用其生成了。我们不管前端,我们只来谈加载方式。让我们看一个Control中的Add方法

            [ControllerAction]
            
    public void Add(string name) {
                Task task 
    = null;
                
    if (String.IsNullOrEmpty(name) == false{
                    task 
    = _taskDB.AddTask(name);
                }


                
    if (IsAjaxRequest) {
                    
    if (task != null{

                        RenderView(
    "TaskView", task);

         
                    }

                }

                
    else {
                    
    if (task != null{
                        RedirectToAction(
    "List");
                    }

                    
    else {
                        Dictionary
    <stringobject> viewData = new Dictionary<stringobject>();
                        viewData[
    "Tasks"= _taskDB.GetTasks();
                        viewData[
    "ShowAddTaskError"= true;

                        RenderView(
    "List", viewData);
                    }

                }

            }

    RenderView会呈现控件的ui,(page,usercontrol都是控件).此代码我们可以看到如果用ajax模式,则会转到TaskView用户控件这里,其本质还是输出UserControl的数据,然后前端得到数据并呈现。但这种做法个人认为不好,每个Action都需要去写if else的语句。我想应该分离出来。

    四。控件Id与Name

    上次发的随笔篇幅太小,被刷了下来,希望这次没这么倒霉。但我还是希望大家看看修改服务器控件的ID和Name ,解决大家的痛,我们是有办法解决。最后阿门,愿MVC模式与控件同在,呵呵。我可不想 <% %> 横行霸道。

    五.让数据绑定控件
    代码更漂亮

    让我们来看个Repater控件的传统应用

    <asp:Repeater ID="normalArticleList" runat="server">
        
    <ItemTemplate>
            
    <div class="textbox">
                
    <div class="textbox-title">
                    
    <h4><onclick="<%# urlFormats.ArticleConent(Convert.ToInt32(Eval("ArticleID").ToString()))%>" href="#"><span runat=server visible=<%# Eval("IsTop")%>>[置顶]</span><%Eval("Title")%></a>
                    
    </h4>
                    
    <div class="textbox-label">
                        [
                        
    <%Eval("PostTime")%>
                        | 
    <%=lang["author"]%><onclick="<%# urlFormats.UserDetail(int.Parse(Eval("AuthorID").ToString()))%>" href="#"><%Eval("Author"%></a> ]</div>
                
    </div>
                
    <div class="textbox-content">
                    
    <%# GetContent(Eval("Content0").ToString(), Eval("Content1").ToString())%><%--<%# Eval("Content1"%>--%></div>
                
    <div class="textbox-bottom">
                    
    <asp:PlaceHolder ID="actionLinkPanel" runat="server">
    <href="articleManage.aspx?act=edit&id=<%# Eval("ArticleID") %>" title="<%=lang["edit"]%>">
                        
    <img src="/styles/default/images/icon_edit.gif" alt="<%=lang["edit"]%>
    " />
                    
    </a><href="/articleManage.aspx?act=delete&id=<%# Eval("ArticleID") %>" title="<%=lang["delete"]%>
    ">
                        
    <img src="/styles/default/images/icon_del.gif" alt="<%=lang["delete"]%>" /></a>
     | 
                    
    </asp:PlaceHolder>

    <onclick="<%# urlFormats.ArticleCategoryUrl(Convert.ToInt32(Eval("categoryID").ToString()))%>" href="#"><%=lang["category"]%>:<%Eval("CategoryName")%></a> | <href="?id=<%# Eval("ArticleID") %>"><%=lang["permalink"]%></a> | <onclick="<%# urlFormats.ArticleConent(Convert.ToInt32(Eval("ArticleID").ToString()))%>" href="#commentbox" title="评论"><%=lang["comments"]%>:<%Eval("CommentCount"%></a> | <href="#"><%=lang["trackbacks"]%>:<%Eval("TrackbackCount"%></a> | <%=lang["views"]%>:<%Eval("ViewCount"%>
                
    </div>
            
    </div>
        
    </ItemTemplate>
    </asp:Repeater>

    很好的完成了工作,通过数据绑定语法。可这界面太烦,字段多,金黄色语法就更多,那个心里烦啊,我们还是无法逃避这个问题,而且我们偶尔还会对一些字段进行逻辑判断。我的做法:用Literal控件代替绑定语法,在ItemDataBound事件中完成数据的填充。现在前端
    <asp:Repeater ID="normalArticleList" runat="server">
    <ItemTemplate>
    <div class="textbox">
        
    <div class="textbox-title">
            
    <asp:Literal ID="articleTitle" runat="server"></asp:Literal>
            
    <div class="textbox-label">
                
    <asp:Literal ID="articleLabel" runat="server"></asp:Literal>
            
    </div>
        
    </div>
        
    <div class="textbox-content">
            
    <asp:Literal ID="articleContent" runat="server"></asp:Literal>
        
    </div>
        
    <div class="textbox-bottom">
        
    <asp:Literal ID="articleBottom" runat="server"></asp:Literal>
        
    </div>
    </div>
    </ItemTemplate>
    </asp:Repeater>

    后端
            void normalArticleList_ItemDataBound(object sender, RepeaterItemEventArgs e)
            
    {
                
    if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
                
    {
                    Article item 
    = (Article)e.Item.DataItem;
                  
                    Literal title 
    = (Literal)e.Item.FindControl("articleTitle");
                    Literal articleLabel 
    = (Literal)e.Item.FindControl("articleLabel");
                    Literal articleContent 
    = (Literal)e.Item.FindControl("articleContent");
                    Literal articleBottom 
    = (Literal)e.Item.FindControl("articleBottom");
                    
                    title.Text 
    = RenderNormalTitle(item);
                    articleLabel.Text 
    = RenderNormalLabel(item);
                    articleContent.Text 
    = RenderNormalContent(item);
                    articleBottom.Text 
    = RenderNormalBottom(item);
                    
                }

            }

    这样的写法会漂亮很多,而且数据绑定是通过反射机制的,听过会损失性能。。。

    写了5点了,打住。不好意思,赖,没提供什么代码给大家下载,希望对大家有帮助。祝:元旦快乐,工作顺利。
  • 相关阅读:
    常见消息引擎系统对比
    kafka(一)入门
    pycharm工具的使用
    VMware下安装Ubantu 18.04
    VMware虚拟机下Ubuntu安装VMware Tools详解
    python--or 和 and 表达式
    django使用缓存之drf-extensions
    数据结构--线性表之链表
    Redis配置主从时报错“Could not connect to Redis at 192.168.0.50:6379: Connection refused not connected>”
    Rsync+sersync(inotify)实现数据实时双向同步
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1021611.html
Copyright © 2020-2023  润新知