...

среда, 20 августа 2014 г.

[Из песочницы] Создание удобного обработчика 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-утилитах Битрикса. Но написать свой обработчик и знать как он работает, это как создать первую программу хелло ворлд. Каждый должен создать велосипед, ибо тогда не программист.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий