zoukankan      html  css  js  c++  java
  • ajax的再次封装!

    js的动态加载、缓存、更新以及复用 系列有点卡文,放心会继续的。先来点更基础的,为js的加载做点铺垫。

      jQuery的ajax本来就很方便了,为啥还要在进一步的封装呢?这个首先要看项目的具体需求了,如果觉得不需要,那么完全可以直接用jQuery提供的各种ajax的方法。如果像我似地,感觉不太方便的话,那么完全可以按照自己的想法和需求来再次封装一下。

      需求:

      1、调用的时候更加的简单。

      2、可以灵活的做各种设置和变化。

      3、可以满足一些通用的需求。比如出错的时候给出提示。

      项目现状:

        做ajax请求的时候,会有一个加载的动画,在ajax发起的时候要自动开始,加载完毕之后要自动停止。出错了也要自动停止,并且给出错误提示。请求的URL比较固定,按照增删改查来分类。要可以跨域,也可以不跨域。需要灵活的进行切换。ajax获得数据的同时,还会附带一段调试信息,需要显示出来。有专门的处理函数,但是需要调用。

      实现:

        直接上代码吧。

    //对ajax的封装
    Nature.Ajax = function (ajax) {
        //最基础的一层封装
       
            //定义默认值
            var defaultInfo = {
                type: "GET",                        //访问方式:如果dataPata不为空,自动设置为POST;如果为空设置为GET。
                dataType: Nature.sendDataType,      //数据类型:JSON、JSONP、text。由配置信息来搞定,便于灵活设置
                cache: true,                        //是否缓存,默认缓存
                xhrFields: {
                    //允许跨域访问时添加cookie。cors跨域的时候需要设置
                    withCredentials: true
                },
                urlPata: {},//url后面的参数。一定会加在url后面,不会加到form里。
                formPata: {},//表单里的参数。如果dataType是JSON,一定加在form里,不会加在url后面;如果dataType是JSONP的话,只能加在url后面。
    
                //url:  //依靠上层指定
    
                //timeout: 2000,
                error: function() {
                },  //如果出错,停止加载动画,给出提示。也可以增加自己的处理程序
    
                success: function() {
                } //成功后显示debug信息。也可以增加自己的处理程序
            };
    
            //补全ajaxInfo
            if (typeof ajaxInfo.dataType == "undefined") {
                ajaxInfo.dataType = defaultInfo.dataType;
            }
            
            if (typeof ajaxInfo.formPata == "undefined") {
                ajaxInfo.type = "GET";
            } else {
                if (ajaxInfo.dataType == "JSON") {
                    ajaxInfo.type = "POST";
                } else {    //get或者jsonp
                    ajaxInfo.type = "POST";
                }
                ajaxInfo.data = ajaxInfo.formPata;
    
            }
    
            if (typeof ajaxInfo.cache == "undefined") {
                ajaxInfo.cache = defaultInfo.cache;
            }
       
    
    
            //处理URL
            if (typeof ajaxInfo.urlPata != "undefined") {
                var tmpUrlPara = "";
                var para = ajaxInfo.urlPata;
                for (var key in para) {
                    tmpUrlPara += "&" + key + "=" + para[key];
                }
    
                if (ajaxInfo.url.indexOf('?') >= 0) {
                    //原地址有参数,直接加
                    ajaxInfo.url += tmpUrlPara;
                } else {
                    //原地址没有参数,变成?再加
                    ajaxInfo.url += tmpUrlPara.replace('&', '?');
                }
            }
    
            //开始执行ajax
            $.ajax({
                type: ajaxInfo.type,
                dataType: ajaxInfo.dataType,
                cache: ajaxInfo.cache,
                xhrFields: {
                    //允许跨域访问时添加cookie
                    withCredentials: true
                },
                url: ajaxInfo.url,  
                data: ajaxInfo.data,
                //timeout: 2000,
                error: function() { //访问失败,自动停止加载动画,并且给出提示
                    alert("提交" + ajaxInfo.title + "的时候发生错误!");
                    if (typeof top.spinStop != "undefined")
                        top.spinStop();
                    if (typeof ajaxInfo.error == "function") ajaxInfo.error();
                },
    
                success: function (data) {
                    if (typeof(parent.DebugSet) != "undefined")
                        parent.DebugSet(data.debug);  //调用显示调试信息的函数。
                    
                    if (typeof (ajaxInfo.ctrlId) == "undefined")
                        ajaxInfo.success(data);
                    else {
                        ajaxInfo.success(ajaxInfo.ctrlId, data);
                    }
    
                }
            });
        
    
       
    
    };

        这是最底层的封装,然后是根据URL的封装,其实就是避免在代码里到处写URL的问题。

     1 Nature.Data.MetaData = function () {
     2 
     3     var ajax = Nature.Ajax;//简化一下
     4 
     5 
     6     /*获取页面视图的元数据*/
     7     this.ajaxGetMeta = function (ajaxData) {
     8 
     9         ajaxData.url = Nature.resourceUrl + "/MetaData/GetMeta.ashx";
    10         ajaxData.cache = false;
    11         
    12         ajax(ajaxData);
    13     };
    14 
    15     
    16 
    17 }
    18 
    19 Nature.Data.CusData = function () {
    20 
    21     var ajax = Nature.Ajax;
    22     
    23   34     //获取客户数据
    35     this.ajaxGetData = function(ajaxData) {
    36 
    37         //增删改查服务的网址
    38         var url = Nature.resourceUrl;
    39         if (typeof ajaxData.url == "undefined")
    40             url += "/Data/GetData.ashx";
    41         else
    42             url += ajaxData.url;
    43 
    44         ajaxData.url = url;
    45         ajaxData.cache = false;
    46 
    47         ajax(ajaxData);
    48         
    49     };
    50     
    51     /*删除数据*/
    52     this.ajaxDeleteData = function (ajaxData) {
    53         var url = Nature.resourceUrl;
    54         
    55         if (typeof ajaxData.url == "undefined")
    56             url += "/Data/GetData.ashx";
    57         else
    58             url += ajaxData.url;
    59         
    60         ajaxData.url = url;
    61         ajaxData.cache = false;
    62 
    63         ajax(ajaxData);
    64     };
    65     
    66 
    67 }

        这个是按照增删改查的URL地址来定的几个函数。主要目的就是处理具体的URL,避免代码里面到处都是URL的混乱问题。

        最后就是具体应用的地方了。

     1  var load = new Nature.Data.MetaDate();
     2 
     3   load.ajaxGetMeta({
     4             urlPata: { action: "tree", mdid: 0, dbid: dataBaseId, ProjectID: projectId, cacheKey: 0 },
     5             title: "获取XXX",
     6             success: function (msg) {
     7                 
     8                 if (typeof top.__cache == "undefined")
     9                     top.__cache = {};/* 开辟缓存空间 */
    10                  
    11                 top.__cache.treeMeta = msg.data;
    12                 
    13                 create2(msg.data);
    14             }
    15         });

      这样调用起来就比较简单了,避免了一些常用且固定的参数的设置,比如type、dataType、cache、url等。可能有些童鞋会想了,不是有$.get和$.post了吗,比你的更简洁吧,你还自己折腾啥!

      $.get和$.post确实更简洁,但是不够灵活,比如cache的设置,有的时候需要缓存,有的时候不需要缓存。再比如type,有的页面需要跨域,有的地方不需要跨域。有的时候要根据项目来统一设置(切换)。所以我自己折腾了一下。

      详细说明:

      默认参数里的几个属性的含义。

      1、title。ajax有可能出错,出错了就应该有个提示。但是一个页面往往有多个ajax,到底是哪个出错了?所以我设置了一个title的属性,在error的时候 alert("提交" + ajaxInfo.title + "的时候发生错误!");这样就比较清晰了,至少按照title的属性值来find一下,可以快速定位。

      2、urlPata和formPata。jQuery的ajax只有一个data的属性。当get的时候,会把data放到URL里面,传递给服务器;当POST的时候,会把data放在form里面,提交给服务器。这个似乎挺好,但是在post的时候,我需要明确的把一些参数放在URL里面,一些参数放在form里面。这个就不能都放在data里面,我还得自己去拼接URL。麻烦还爱出错。所以我就分成了两个属性urlPata和formPata。

        urlPata肯定会出现在URL里面。formPata就需要根据情况而定了。JSON的时候会放在form里面,JSONP的时候就只能放在URL里面了。

      3、xhrFields。这个就涉及到HTML5.0里面对post跨域的支持问题了。一般提到跨域,想到的都是JSONP,但是JSONP是伪装成<script>来实现的跨域,由于js并不支持post,所以导致无法实现post的跨域提交。现在HTML5.0解决了这个问题,就是cors。我也是最近几天才弄明白这个。后来发现jQuery也是支持cors的。jQUery.support.cors = true; 这样就可以开启cors。然后在测试的时候发现个问题,出于安全考虑,默认情况下cors的跨域是不会附带cookie信息的,需要手动设置。于是就出现了xhrFields这一段。当然要完全实现cors,服务器端也需要做相应的设置,这个会在我的《细说跨域那点事》里面有详细的说明。

      4、error。ajax访问,难免会出现点小意外,有的是服务器返回的值有问题,有时候是服务器报错了。那么要怎么办呢?于是就出现了这个error的统一处理函数。在这里首先会根据title属性给出一个提示,告诉用户,访问出错了。然后会把加载的动画提示给停掉。一开始在出错的时候没有去停止加载动画,好多用户就更我说,你那个页面,转呀转呀,转了n就都没反应。所以我就加上了这段。

      5、success。成功之后,调用显示调试信息的函数,把调试信息给显示出来。便于调试和优化。

      6、defaultInfo。首先以传递过来的ajaxInfo为准,如果有了就按照ajaxInfo的来,如果没有指定,就使用defaultInfo提供的对应属性来赋值。就是一个缺省值的作用。

      折腾的好处:

      一开始error里面,没有alert的提示,很不可思议吧,但是确实是没有。后来想想还是加上吧,那么我改一个地方就ok了,不需要到处都去改。后来又加上了停止加载动画的功能,现在想想,是不是也要把显示调试信息的给加上呢?有些错误也是会返回调试信息的呀。如果加的话,也是只需要改一个地方就ok了。

      以前不知道cors,学会cors之后发现要附带cookie的话,还要加上xhrFields,那好吧,就一个地方加上就行了,也不需要到处去改。

      总之,当变化发生的时候,我只需要改一个地方就ok了,我不需要到处去改,还容易漏掉某某。

    ps:

    这里跳过了一个步骤,就是“缓存”。不是ajax带的cache,而是类似于本地储存(Local Storage)的东东。这个以后会详细说明。

  • 相关阅读:
    032 Gradle 下载的依赖jar包在哪?
    031 can't rename root module,Android Studio修改项目名称
    030 Cannot resolve symbol'R' 问题解决汇总大全
    029 Android Studio层级显示目录文件
    028 You are about to commit CRLF line separators to the Git repository.It is recommended to set the core. autocrlf Git attribute to true to avoid line separator issues If you choose Fix and Comit ,
    027 【Android基础知识】Android Studio 编译慢及 Adb connection Error:远程主机强迫关闭了一个现有的连接
    026 Android Studio 和Gradle版版本对应关系
    025 Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm
    024 Android Studio上传项目到Github 最全记录
    023 解决AndroidStudio下载gradle慢的问题
  • 原文地址:https://www.cnblogs.com/jyk/p/3790609.html
Copyright © 2011-2022 走看看