Вроде бы оно и быстро реализовано на 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-утилитах Битрикса. Но написать свой обработчик и знать как он работает, это как создать первую программу хелло ворлд. Каждый должен создать велосипед, ибо тогда не программист.
ссылка на оригинал статьи http://habrahabr.ru/post/233965/
Добавить комментарий