Это может быть сложно, если вы хотите наблюдать и только перехватывать. Код довольно прост. мой выбор для прото-изменения одного запроса будет Class.refactor
из mootools-more, если доступно:
// enable log func...
Class.refactor(Request, {
success: function(text, xml){
this.previous(text, xml);
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
},
failure: function(){
this.previous();
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
}
});
и общий бит - это то же самое, что и вы.
// assign a logger function
Request.monitor = function() {
console.log("onComplete", this.response.text);
};
// call a simple request object.
new Request({
url: "/echo/html/",
method: "post",
data: {
html: "hello"
}
}).send();
Причина: он будет работать независимо от изменений ядра mootools. Ему не важно, что это за функциональный код, он будет работать после нашего оригинала и не сломается, если в будущем
огромное изменение API не произойдет *1012*
Вместо этого вы также можете изменить классы с помощью implement
, хотя это не будет учитывать изменения в ядре mootools, какими бы вероятными они ни были. на практике это означает, что необходимо скопировать и вставить текущий метод в методы и добавить к нему - к счастью, короткие методы, которые мы хотим изменить:
Request.implement({
success: function(text, xml){
this.onSuccess(this.processScripts(text), xml);
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
},
failure: function(){
this.onFailure();
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
}
});
И, наконец, вы даже можете сохранить старый низкий уровень var oldsuccess = Request.prototype.success
, сделать свое дело и oldsuccess.apply(this, arguments)
.
Сложность в том, что подклассы Request, такие как HTML и JSON - если они уже определены, они скопируют старый прототип, и ваш регистратор сделает это. вместо этого вы можете сделать это как небольшой объект и внедрить его во все классы Request.
Что-то вроде этого элегантно и может работать, но только если методы успеха одинаковы в коде, иначе - это сломает вещи в подклассах:
(function() {
var changes = {
success: function(text, xml){
this.onSuccess(this.processScripts(text), xml);
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
},
failure: function(){
this.onFailure();
Request.monitor && typeof Request.monitor == "function" && Request.monitor.apply(this, arguments);
}
};
[Request, Request.HTML, Request.JSON].invoke('implement', changes);
})();
комбинация из последнего метода + orig proto - это то, что вам действительно нужно, так как функции успеха различаются по всем 3 ...
edit это становится смешным. как я уже сказал, не самая простая задача ...
это, вероятно, будет финальная версия / рефактор, который я буду использовать на производстве, протестировать и работать со всеми 3 классами. Имейте в виду, что методы выполняются ПЕРЕД дополнительным анализом JSON или HTML. это низкий уровень регистрации. иначе, рефакторинг будет идти вместо onSuccess и onFailure.
(function() {
// what we will extend
var classes = [Request, Request.HTML, Request.JSON],
// map to a text name
mapper = ["Request", "Request.HTML", "Request.JSON"],
// store reference to original methods
orig = {
onSuccess: Request.prototype.onSuccess,
onFailure: Request.prototype.onFailure
},
// changes to protos to implement
changes = {
onSuccess: function(){
Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
orig.onSuccess.apply(this, arguments);
},
onFailure: function(){
Request.Spy && typeof Request.Spy == "function" && Request.Spy.apply(this, arguments);
orig.onFailure.apply(this, arguments);
}
};
classes.invoke('implement', changes);
// allow us to tell which Class prototype has called the ajax
Request.implement({
getClass: function() {
var ret;
Array.each(classes, function(klass, index) {
if (instanceOf(this, klass)) {
ret = mapper[index];
}
}, this);
return ret;
}
});
})();
// to enable spying, just define Request.Spy as a function:
Request.Spy = function() {
console.log(this.getClass(), arguments);
};
// test it via normal Request
new Request({
url: "/echo/html/",
data: {
html: "normal data"
}
}).send();
// test via HTML
new Request.HTML({
url: "/echo/html/",
data: {
html: "<p>normal data</p>"
}
}).send();
// test via JSON
new Request.JSON({
url: "/echo/json/",
data: {
json: JSON.encode({'normal':'data'})
}
}).send();
jsfiddle: http://jsfiddle.net/dimitar/3rnKe/