[Из песочницы] Создание удобного обработчика AJAX-запросов
Многие сталкивались с проблемой огромного количества post и get запросов по ходу разработки сайта. В частности, в разработке на jQuery, где не один запросик-стучалка, а куча запросов в тех-же самых магазинах: корзина, избранное, фильтр. Да что я распыляюсь. Все и так прекрасно понимают прелести разработки больших проектов.Вроде бы оно и быстро реализовано на JQ…, но как-то не очень. Все равно тратятся драгоценные символы и время на создание удобного кода.
Столкнувшись с этой проблемой в 105 раз, решил — хватит. Пора что-то менять. И поменял.Суть приёма такая: Для обработки запросов используем один файл с классом-обработчиком. Он принимает запросы и роутит их на соответствующий метод объекта обработчика. Чтобы не заморачиваться долго, было решено и коллбэк выводить обязательно (см. функцию retJSON) из свойства объекта CLBK.Соответственно, отправление/получение происходит также с помощью одного метода. В параметры JS-метода включается отдельно название метода и отдельно — все остальное.
Данный способ позволил мне:1. Избавиться от тучи файлов-обработчиков. 2. Хоть как-то привести код в порядок, вместо обыкновенного JQ-бедлама.3. Создать определённую структуру кода и даже возможность расширения приложения.4. Повысить читаемость кода. Будучи программистом культурным («Господи Иисусе!», — возопят знатоки предмета. — «ты же совсем не понимаешь принципов программирования, какая тут культура.» Может быть где-то недочитал матчасть, но плевать я хотел на ихнее мнение, если честно. Мне так комфортно) в последнее время стал задумываться и о людях, которые после меня будут разбираться в моих строчках. Посему потратил пару дополнительных часов.
Имхо, данное решение множество раз уже было воссоздано во фреймворках разного толка и сорта. Однако приятно иметь своё собственное решение. И пользоваться им.
Ниже скрипты и пример использования обработчика.
var JQ = $; var Core = {
rmvFrmBskt: function (id){ this.request (arguments.callee,{ID: id}, function (data){ if (data.status === «OK») Core.getBskt (); }) },
request: function (method, params, callback_fnc){ if ( ( typeof method!== 'string'&& typeof method!== «function» )|| typeof params!== «object»|| params === null ) throw «Core.request: Arguments isn’t valid»; if (typeof method!== 'string') method = Hlp.getMthName (this, method); if (method==='') throw «Core.request: method is hollow»; JQ.post (»/callback.php»,{«method»: method, «params»: params}, function (data, callback){ try{var JSONobj = JSON.parse (data)} catch (e){ throw (e); } if (JSONobj.error){ throw «Core.request::» + JSONobj.error; } if (JSONobj.notify_text){ alert (JSONobj.notify_text); throw «Core.request::» + JSONobj.notify_text; } if (JSONobj.echo){ if (Util.bid («debugdiv»)) Util.rmv (Util.bid («debugdiv»)); var dbg = Util.crt («div», «debugdiv»); body.appendChild (dbg); dbg.innerHTML = JSONobj.echo; } callback_fnc (JSONobj); }); }
var Hlp = {
getMthName: function (obj, mth) { var mthName = ''; for (var i in obj) { if (obj[i]===mth){ mthName = i; break; } }; return mthName; } }
var Util = { bid: function (id){ if (! id){ return document.getElementById (id); } }, rmv: function (Node){ Node.parentNode.removeChild (Node, Node.parentNode); }, rmvAllCh: function (Node){ var cnt = Node.children.length; for (var k = 0; k < cnt; k++){ Util.rmv(Node.children[0]); } }, bc: function(className){ var Node = document.getElementsByClassName(className); if(Node.length==1){ return Node[0]; }else{ return Node; } }, crt: function(Node, className, attr){ var tmp = document.createElement(Node); if((typeof className === 'string')&&(className!='')){ tmp.className = className; } if(typeof attr === 'object'&&attr != null){ for(var i in attr){ tmp[i] = attr[i]; } } return tmp; }
} Немного PHP
class CallBack{ public static $CLBK = Array (); static function router (){ if (! CModule: IncludeModule («catalog»)|| ! CModule: IncludeModule («sale»)|| ! CModule: IncludeModule («iblock»)){ CallBack: retJson (Array («error»=>«PHP CModule isn’t included»)); die (); } if (isset ($_REQUEST)&&! empty ($_REQUEST)&&method_exists («CallBack», $_REQUEST['method'].«Clbk»)){ $methodName = $_REQUEST['method'].«Clbk»; CallBack::$methodName ($_REQUEST['params']); }else{ CallBack: retJson (Array («error»=>«PHP Callback.router: invalid arguments»)); } } static function retJson (){ if (! is_array (self::$CLBK)) die (); echo json_encode (self::$CLBK); }
public function rmvFrmBsktClbk ($PARAMS){ CSaleBasket: Delete ((int)$PARAMS['ID']); self::$CLBK['status'] = «OK»; } }
CallBack: router (); CallBack: retJson (); Как могут заметить знающие программисты, решение написано для 1С-Битрикс. Да, знаю, где-то там в дебрях документации есть строки о встроенных AJAX-утилитах Битрикса. Но написать свой обработчик и знать как он работает, это как создать первую программу хелло ворлд. Каждый должен создать велосипед, ибо тогда не программист.