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