为了账号安全,请及时绑定邮箱和手机立即绑定

Ajax 回忆录

标签:
架构

说起Ajax,并没有什么特别的感觉,只记得曾经接触过这么几种:

一:Net2.0自带的ICallbackEventHandler

那时候从VS2003刚等到VS2005一出来之际,就看了大量的视频教程,从中也学到了这个ICallback的用法。

我将之用在一个CMMI的课程设计里,做的一个图书管理系统,好像在上传图片的时候,为了不刷新某个东东而特意用的。

 

 

二:Atlas

复制代码

只记得很久前,2006还是2007之际。

那时的Atlas框架刚出来的时候,我一路追着风。关注的flychen的博客,虽然他的文章多数是翻译。

那时候的Atlas很牛B,特效特牛,随便拖一个都是一个赞,我的毕业设计里几乎用上了所有的Atlas控件,就是这份特效为了毕设和第一份工作带来了自信。

那时候的毕业设计做的是一个QQ空间,实现的功能就是:主页汇总,日志,留言,音乐盒,相册,换肤,加一个聊天室。

那个是一个劲的特效,随便点一个,都忽的一声出来,背景随便就黑屏的那种。什么折叠效果,乱七八糟的,什么音乐盒,还能到处拖。

到了后来升到asp.net Ajax版本之后,就再也没那种激情追求什么特效了,把B还给牛了

复制代码

 

 

三:Prototype

在我的毕业设计里,有音乐盒这东西,音乐盒的播放器是从网上下载的。里面用到了一个prototype.js来调用播放列表。

于是prototype就成了我的第二个接触的Ajax封装体了,在里面也只是小小用了一下。

 

 

四:XMLHttpRequest

复制代码

还是2007年,要实现一个用户上传图片时,可以拖拉范围红色框同时会放大用户的图片,
用户在一个框选头像后,确定截图上传。
这时用上XMLHttpRequest了,什么新瓶装旧水的言论也略听一二了。
技术总监说这些Ajax早在N年前他就在用了,原理还是Iframe这东西。
后来很多时一直还是用这个。复制代码

 

 

五:Jquery

这东东我本人没有用过,不过随着它的流行,我在以前兼职教师时,给我学生介绍过,也按着文档实际操作过几个例子,多数还是讲原理的东西。

 

 

 

一路走过来,

 

复制代码

从不懂性能[哪个帅点用哪个]->很牛B

性能优先[哪个性能最好用哪个]->只有牛,没有B

到性能取舍[哪个适合项目用哪个]->没牛也没B

这是一个领悟过程
 回归是一种自然
复制代码

 

 

 

下面说下用Net2.0自带的ICallbackEventHandler实现封装的一种应用:省市区的联动实现

 

首先:新建一个PageBase.cs基类,继承自System.Web.UI.Page和ICallbackEventHandler接口,代码如下:

PageBase.cs

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

/// <summary>
/// PageBase 的摘要说明
/// </summary>
public class PageBase:System.Web.UI.Page,ICallbackEventHandler
{
    #region ICallbackEventHandler 成员
    /// <summary>
    /// Ajax方法时的回调结果
    /// </summary>
    public string ajaxCallBackResult = null;
    /// <summary>
    /// 注册Ajax方法
    /// 调用方法名:callAjax(arg)
    /// 回调方法名:callBack(result)
    /// </summary>
    public void RegisterAjax()
    {
        RegisterAjax(this, "callAjax", "callBack");
    }
    public void RegisterAjax(Control ct, string functionName, string callBackName)
    {
        if (!ct.Page.ClientScript.IsClientScriptBlockRegistered(functionName))
        {
            string callBack = ct.Page.ClientScript.GetCallbackEventReference(ct, "arg", callBackName, null);
            string clientFunction = "function " + functionName + "(arg){" + callBack + "}";
            ct.Page.ClientScript.RegisterClientScriptBlock(ct.Page.GetType(), functionName, clientFunction, true);
        }
    }
    public string GetCallbackResult()
    {
        return ajaxCallBackResult;
    }
    public virtual void RaiseCallbackEvent(string eventArgument)
    {
        if (CallAjaxEvenHandle != null)
        {
            CallAjaxEvenHandle(eventArgument);
        }
        else
        {
            ajaxCallBackResult = eventArgument;
        }
    }
    public delegate void CallAjaxFunction(string para);
    public event CallAjaxFunction CallAjaxEvenHandle;
    #endregion
}

说明:

上面的基类中封装了一些基础的注册方法,下面演示如何调用。

 

简单测试调用:

普通页面后台.cs代码,继承自PageBase

复制代码

public partial class _Default :PageBase
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RegisterAjax();
    }
}复制代码

 

接着页面html代码如下:

复制代码

<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
    <form id="form1" runat="server">
<input type="button" value="pages" onclick="callAjax('hello')" />
<script>function callBack(result){alert(result);}</script>
    </form>
</body>
</html>复制代码

 

OK,点击就可以出现hello了。

 

扩展应用:很多时候,我们需要在用户控件里实现Ajax调用。

 

这里,也做一个简单调用示例:

控件cs代码:

控件CS代码

public partial class Controls_Head : System.Web.UI.UserControl,ICallbackEventHandler
{
    string callbackResult;
    protected void Page_Load(object sender, EventArgs e)
    {
        ((PageBase)this.Page).RegisterAjax(this, "callAjaxControl", "callbackControl");
    }
    #region ICallbackEventHandler 成员
    public string GetCallbackResult()
    {
        return callbackResult;
    }
    public void RaiseCallbackEvent(string eventArgument)
    {
        callbackResult = eventArgument;
    }

    #endregion
}

 

用户控件html代码:

控件html代码

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Head.ascx.cs" Inherits="Controls_Head" %>
<input type="button" value="control" onclick="callAjaxControl('helloControl')" />
<script>function callbackControl(result){alert(result);}</script>

 

OK,点击结果也同样出来了。

 

以下进一步示范怎么实现联动:

 

复制代码

过程:

1:默认先绑定一个省

2:选择省时Ajax请求(发送ID到后台

3:后台查询数据库,把省下的市按规则组合发回前台

4:前台js按规则拆分字符串
5:js清空市并连动区与县的下拉框(或者说叫复位)

6:js创建下拉的项option,并添加到市下拉里

重复一下就是几级联动了,最后完成

复制代码

 

 

这里的js会做很多事件:发送ajax请求->接收result->分隔字符->复位下拉框->创建下拉option并添加

 

这里先添加一个AreaCity.js,把上面的东西都实现,代码如下:

 AreaCity代码[点下面的一条框出来]


function GetSonData(parentID,sonDropDownID)

   if(parentID=="请选择" || !parentID)
   {
        SetDropDownToInit(sonDropDownID);
   }
   else
   {
        callAjax(parentID+","+sonDropDownID);
   }
}
function callBack(result)

    if(result && String(result).indexOf('&')>-1)
    {
        var listString=result.split('&')[0];
        var dropDownID=result.split('&')[1];
        if(!listString){SetDropDownToInit(dropDownID)}
        else{createNode(listString,dropDownID);}
    }
}
function createNode(listString ,dropDownID)
{  
    var dropDown=$(dropDownID);
    if(!dropDown){return;}
    InitDropDown(dropDown);
    if(listString)
    {
        var strValues = listString.split('|');
        for(var i=0;i<strValues.length;i++)
        {
            var val = strValues[i].split(',')[0];
            var txt = strValues[i].split(',')[1];
            
            var optionObj = document.createElement("option");
            optionObj.value = val;
            optionObj.innerText = txt;
            dropDown.appendChild(optionObj);
        }
        dropDown.selectedIndex=1;
    }
}
function InitDropDown(dropDown)
{
    while(dropDown.length>0)
    {
        dropDown.removeChild(dropDown.firstChild);
    }
    var optionObj = document.createElement("option");
        optionObj.value = '';
        optionObj.innerText = '请选择';
        dropDown.appendChild(optionObj);
}
function SetDropDownToInit(dropDownID)
{
    InitDropDown($(dropDownID));
    switch(dropDownID)
    {
        case "ddlID_City":
            InitDropDown($('ddlID_County'));
            InitDropDown($('ddlID_Town'));
            break;
            case "ddlID_County":
            InitDropDown($('ddlID_Town'));
            break;
    }
}
function $(id){return document.getElementById(id);}

 

好,我们先看html代码:引入areacity.cs并拉几个下拉控件上去:

html代码

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <script class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="js/AreaCity.js"></script>
</head>
<body>
    <form id="form1" runat="server">
        省:
        <asp:DropDownList ID="ddlID_Province" runat="server" onchange="GetSonData(this.value,'ddlID_City')">
        </asp:DropDownList><br />
        市:
        <asp:DropDownList ID="ddlID_City" runat="server" onchange="GetSonData(this.value,'ddlID_County')">
        <asp:ListItem Text="请选择"></asp:ListItem></asp:DropDownList><br />
        区:
        <asp:DropDownList ID="ddlID_County" runat="server" onchange="GetSonData(this.value,'ddlID_Town')">
        <asp:ListItem Text="请选择"></asp:ListItem></asp:DropDownList><br />
        镇:
        <asp:DropDownList ID="ddlID_Town" runat="server">
        <asp:ListItem Text="请选择"></asp:ListItem>
        </asp:DropDownList>
    </form>
</body>
</html>

 

现在看一下后台代码cs,这里不用数据库,临时用Dic字典组合充当数据:

 

cs代码

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Collections;
public partial class ProvinceCity : PageBase
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {

            RegisterAjax();
            //一开始绑定省
            ddlID_Province.DataSource = GetChild(0);
            ddlID_Province.DataValueField = "key";
            ddlID_Province.DataTextField = "value";
            ddlID_Province.DataBind();
            ddlID_Province.Items.Insert(0, "请选择");
        }
    }
    public override void RaiseCallbackEvent(string eventArgument)
    {
        if (eventArgument.Contains(","))
        {
            string parentID = eventArgument.Split(',')[0];
            //根据ID查数据库
            Dictionary<int, string> items = GetChild(int.Parse(parentID));
            if (items.Count > 0)
            {
                foreach (KeyValuePair<int, string> itemPair in items)
                {
                    ajaxCallBackResult += itemPair.Key + "," + itemPair.Value + "|";
                }
                ajaxCallBackResult = ajaxCallBackResult.TrimEnd('|');
            }

            ajaxCallBackResult += "&" + eventArgument.Split(',')[1];//附加回去下拉列表控件ID
        }
    }
    #region 假设这里为数据库查询
    protected Dictionary<int, string> GetChild(int parentID)
    {
        Dictionary<int, string> items = new Dictionary<int, string>();
        switch (parentID)
        {
            case 0:
                items.Add(1, "广东省");
                items.Add(2, "广西省");
                break;
            case 1:
                items.Add(11, "汕尾市");
                items.Add(12, "广州市");
                break;
            case 2:
                items.Add(21, "桂林市");
                items.Add(22, "南宁市");
                break;
            case 11:
                items.Add(111, "海丰县");
                break;
            case 12:
                items.Add(121, "天河区");
                break;

            case 111:
                items.Add(1111, "城东");
                items.Add(1112, "城西");
                break;

        }
        return items;
    }
    #endregion
}

 


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消