我的网站大量使用ajax来编辑用户详细信息。我想创建一个管理员模式,以便管理员可以编辑用户的详细信息,而无需以他们身份登录(因此必须知道他们的密码。)
我计划让我网站上的所有用户详情页面都使用参数id
。如果页面访问者以管理员身份登录,我希望将此id附加到发送的所有ajax请求的数据中。因此,如果用户以管理员身份登录,我将在mootools库加载后向页面中注入一些javascript,强制Request方法在发出请求时始终携带此id。
我该如何实现?
这是Request类的发送方法:
send: function(options){
if (!this.check(options)) return this;
this.options.isSuccess = this.options.isSuccess || this.isSuccess;
this.running = true;
var type = typeOf(options);
if (type == 'string' || type == 'element') options = {data: options};
var old = this.options;
options = Object.append({data: old.data, url: old.url, method: old.method}, options);
var data = options.data, url = String(options.url), method = options.method.toLowerCase();
switch (typeOf(data)){
case 'element': data = document.id(data).toQueryString(); break;
case 'object': case 'hash': data = Object.toQueryString(data);
}
//---------
//LOOK HERE
//---------
if (this.options.format){
var format = 'format=' + this.options.format;
data = (data) ? format + '&' + data : format;
}
if (this.options.emulation && !['get', 'post'].contains(method)){
var _method = '_method=' + method;
data = (data) ? _method + '&' + data : _method;
method = 'post';
}
if (this.options.urlEncoded && ['post', 'put'].contains(method)){
var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding;
}
if (!url) url = document.location.pathname;
var trimPosition = url.lastIndexOf('/');
if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
if (this.options.noCache)
url += (url.contains('?') ? '&' : '?') + String.uniqueID();
if (data && method == 'get'){
url += (url.contains('?') ? '&' : '?') + data;
data = null;
}
var xhr = this.xhr;
if (progressSupport){
xhr.onloadstart = this.loadstart.bind(this);
xhr.onprogress = this.progress.bind(this);
}
xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password);
if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true;
xhr.onreadystatechange = this.onStateChange.bind(this);
Object.each(this.headers, function(value, key){
try {
xhr.setRequestHeader(key, value);
} catch (e){
this.fireEvent('exception', [key, value]);
}
}, this);
this.fireEvent('request');
xhr.send(data);
if (!this.options.async) this.onStateChange();
if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this);
return this;
}
在我标记的地方,该方法似乎为请求添加了一些额外的数据。我认为这将是添加我的代码的好地方。我可以覆盖这个方法来包含这样的东西:
if (_USER_ID_TO_EDIT){
var id= 'userIdToEdit=' + _USER_ID_TO_EDIT;
data = (data) ? id+ '&' + data : id;
}
但是,这不是一个很好的解决方案,因为这意味着如果库中的send()函数有任何更改,我的代码将变得不同步(我喜欢使用最新的库版本。)< / p>
有没有更好的方法来做到这一点(我的方法在这里工作)?如何在不更改~20 .js文件的情况下为Request
类发送的所有请求添加内容,并在我的网站上的其他位置更改此类的约100次使用?
答案 0 :(得分:1)
Request.admin = new Class({
Extends: Request,
initialize: function(options) {
this.parent(options);
},
send: function(options) {
// example, add to the data being sent admin id and a delay
options = Object.merge({
data: {
adminid: "foo",
delay: 5 // testing with 5 sec delay
}
}, options || this.options);
this.parent(options);
}
});
new Request.admin({
url: '/echo/html/',
data: {
html: "<p>original data here. foobar</p>"
},
method: 'post',
onComplete: function() {
document.id('target').set("html", this.response.text);
}
}).send();
http://jsfiddle.net/dimitar/x2pBu/
我认为这是更好的做法。您还需要覆盖.get
方法。
另一种解决方案是通过重构来更改Request原型本身,而不是直接编辑它 - 您可以使用mootools-more或Class.refactor
中的Request.implement({send: ... });
,以便Request的所有子类从中受益(Request。 HTML和Request.JSON和Request.Queue等)。
你甚至可以做var orig = Request.prototype.send; Request.prototype.send = function() {... something to options; orig.call(this, options); }
等等。
这种改变的缺点是你的Request类中会出现意外行为(即期望某些事情发生的mootools dev会被抓住,数据会在他们不知情的情况下发出,验证器可能会失败等等)。调试可能很困难。将它作为隐式扩展类从维护的角度来看也是有意义的,也是最小的抽象。
不要过于担心未来的兼容性 - mootools 2.0(又名MILK)将采用AMD的方式,旧的mootools代码将从兼容性的角度来看已经过时,尽管API仍然存在)。 1.4分支中可能不会有更多版本。