Chr*_*oph 14 rest extjs parent-child extjs4
我正在访问一个REST服务,它公开了这两个资源,一个父资源和一个子资源:
/users
/users/{userId}/account
Run Code Online (Sandbox Code Playgroud)
因此资源"帐户"不嵌套在资源"用户"中,它必须由第二个请求访问.这里有REST API的例子,例如这里
我使用这些模型将用户及其帐户映射到Ext Js 4数据模型:
用户
Ext.define("MyApp.model.User", {
extend: "Ext.data.Model",
fields: [ { name: "id", type: "string" }],
associations: [{
model: "MyApp.model.Account",
name: "account",
type: "hasOne",
reader: "json",
getterName: "getAccount",
setterName: "setAccount",
foreignKey: "accountId"
}
],
proxy: {
type: "rest",
url: "/rest/users",
reader: {
type: "json",
totalProperty: "total",
root: "users"
}
}
});
Run Code Online (Sandbox Code Playgroud)
帐户
Ext.define("MyApp.model.Account", {
extend: "Ext.data.Model",
fields: [ { name: "id", type: "string" }],
belongsTo: "MyApp.model.User",
proxy: {
type: "rest",
reader: { type: "json"}
}
});
Run Code Online (Sandbox Code Playgroud)
帐户代理没有URL(我希望这将基于父用户模型创建).当我调用user.getAccount()时,我得到一个异常,因为代理缺少url.
问题:是否有某种方法来设置模型,以便Ext Js将访问/ users/{userId}/account而无需使用每个父userId手动更新帐户代理URL?
rix*_*ixo 26
你不会从库存Ext类中获得你想要的东西,你将不得不变得有点脏......
根据我的理解,您需要用户的ID加载其帐户,而不是帐户记录本身的ID.所以,我会配置关联来反映:
associations: [{
model: "MyApp.model.Account",
name: "account",
type: "hasOne",
reader: "json",
getterName: "getAccount",
setterName: "setAccount",
// foreignKey: "accountId"
foreignKey: 'id'
}],
Run Code Online (Sandbox Code Playgroud)
这里的一大优势是,当要求用户构建请求的URL时,用户ID将可供代理使用.
现在,为了使用您需要的格式构建URL,我们必须替换代理的buildUrl方法.而且,正如您已经发现的那样,您首先需要一个URL才能使用此方法.
那么,这是我如何配置帐户代理:
proxy: {
type: "rest",
reader: {type: "json"},
// Give it an URL to avoid the error
url: '/rest/users/{}/account',
// Replace the buildUrl method
buildUrl: function(request) {
var me = this,
operation = request.operation,
records = operation.records || [],
record = records[0],
url = me.getUrl(request),
id = record ? record.getId() : operation.id;
// Here's the part honoring your URL format
if (me.isValidId(id)) {
url = url.replace('{}', id);
} else {
throw new Error('A valid id is required');
}
// That's enough, but we lose the cache buster param (see bellow)
return url;
// If we want the cache buster param (_dc=...) to be added,
// we must call the superclass, which will read the url from
// the request.
request.url = url;
return Ext.data.proxy.Rest.superclass.buildUrl.apply(this, arguments);
}
}
Run Code Online (Sandbox Code Playgroud)
此时,我们最终在表单的URL上发出代理触发请求:
rest/users/45/account?id=45
Run Code Online (Sandbox Code Playgroud)
这只是化妆品,但是id查询参数让我烦恼,所以我也会用下面的buildRequest方法替换代理方法:
buildRequest: function(operation, callback, scope) {
var me = this,
params = operation.params = Ext.apply({}, operation.params, me.extraParams),
request;
Ext.applyIf(params, me.getParams(operation));
// if (operation.id !== undefined && params[me.idParam] === undefined) {
// params[me.idParam] = operation.id;
// }
request = new Ext.data.Request({
params : params,
action : operation.action,
records : operation.records,
operation: operation,
url : operation.url,
proxy: me
});
request.url = me.buildUrl(request);
operation.request = request;
return request;
}
Run Code Online (Sandbox Code Playgroud)
并且,在这里......虽然它可行,但我并不真的建议在代理的配置中以这种方式覆盖方法.在现实生活中,你应该从Rest中扩展你自己的代理类,特别是如果你需要配置许多这样的代理......但我希望我给你开始所需的所有成分!
我有同样的问题,我发现rixo的答案绝对令人惊讶.因此我自己采用了它,但后来我做了一些修改,所以这是我目前正在使用的代码.它的优点是它允许您根据自己的喜好绝对格式化服务URL,连接更多的参数.
// Replace the buildUrl method
buildUrl: function (request) {
var me = this,
url = me.getUrl(request);
var added = [];
for(var p in request.params)
{
if (url.indexOf('{' + p + '}') >= 0) {
url = url.replace('{' + p + '}', request.params[p]);
added.push(p);
}
}
for(var a in added)
{
delete request.params[added[a]];
}
// That's enough, but we lose the cache buster param (see bellow)
return url;
// If we want the cache buster param (_dc=...) to be added,
// we must call the superclass, which will read the url from
// the request.
request.url = url;
return Ext.data.proxy.Rest.superclass.buildUrl.apply(this, arguments);
}
Run Code Online (Sandbox Code Playgroud)
这样你可以使用像" / service/{param1}/{param2} /?abc = {param3} " 这样的网址给出"request.params"这样的对象
{"param1":"value1","param2":"value2","param3":"value3"}
并且也不需要覆盖"buildRequest"方法,因为此处使用的任何参数都将从"params"对象中删除,并且以后不会与查询字符串连接.
我希望这有帮助,欢迎任何评论!