将单个对象加载到 sencha touch 中的数据存储中
Posted
技术标签:
【中文标题】将单个对象加载到 sencha touch 中的数据存储中【英文标题】:load single object into a data store in sencha touch 【发布时间】:2011-04-26 14:16:43 【问题描述】:我正在尝试使用 sencha touch 加载单个 json 对象。 当我使用数组时,一切都很好,但是我没有找到将单个对象加载到 Ext.data.Store 中的方法
这是我尝试加载的示例:
"person":"name":"John","surname":"Fox"
它不工作。 在查看this 条目后,
我尝试加载以下内容并成功:
["person":"name":"John","surname":"Fox"]
我的问题是:有没有办法在不带 [ ] 的情况下加载它? 为了做到这一点,我不得不修改我的服务器端代码,这对我来说就像是代码的味道...... 我希望能够加载单个 json 对象而不将其放入列表中。
这是我的 Sencha Touch 代理代码:
Ext.regModel("Person",
fields: ['name','surname']
);
var store = new Ext.data.Store(
model : "Person",
autoLoad : true,
proxy:
type: 'ajax',
url : 'my json url...',
reader:
type: 'json',
record: 'person'
);
顺便说一句 - 我的服务器端代码在 Ruby on Rails 中。
【问题讨论】:
【参考方案1】:Ext 开发团队的 Animal 提供了这个非常有用的解决方案:
reader:
type: 'json',
root: function(data)
if (data.users)
if (data.users instanceof Array)
return data.users;
else
return [data.users];
通过简单地使用函数作为根,您可以确保读取器获取数组中的对象。
【讨论】:
【参考方案2】:更新:使用 sencha 访问单个 json 对象的方法只是发出一个简单的请求,而不使用数据存储。这是执行此操作的代码示例:
Ext.ns('myNS');
Ext.Ajax.request(
url: 'my url',
method: 'GET',
params:
someParam: 'someValue'
,
success: function(result, request)
var json = Ext.decode(result.responseText);
myNS.loadedPerson = json.person;
,
failure: function(result, request)
Ext.Msg.alert('Error!', 'There was a problem while loading the data...');
);
如果您仍然坚持使用数据存储 - 在服务器端有一个可能的解决方案,该解决方案维护一个 restful API: 这是我为了让我的 API 保持安静所做的:
我添加了一个名为 sencha 的新 MIME 类型,它的行为与 json 完全相同,但它也将 json 包装在 [ ] 括号中。
这可能是(也可能是)矫枉过正,但这样就不会干扰我的 JSON API。 这是新 MIME 类型的代码:
Mime::Type.register_alias "application/json", :sencha
#Add the renderer, and register a responder:
require 'action_controller/metal/renderers'
require 'action_controller/metal/responder'
# This is also how Rails internally implements its :json and :xml renderers
# Rarely used, nevertheless public API
ActionController::Renderers.add :sencha do |json, options|
json = ActiveSupport::JSON.encode(json) unless json.respond_to?(:to_str)
# Add [ ] around the response
json = "[#json]"
json = "#options[:callback](#json)" unless options[:callback].blank?
self.content_type ||= Mime::JSON
self.response_body = json
end
# This sets up a default render call for when you do
# respond_to do |format|
# format.sencha
# end
class ActionController::Responder
def to_sencha
controller.render :sencha => resource
end
end
这允许我在客户端定义以下代理(注意格式:'sencha'):
proxy:
type: 'rest',
format: 'sencha',
url : my server url,
reader:
type: 'json',
record: 'person'
这样我仍然可以保持一个restful API,并将Sencha的json表示视为另一种表示资源的方式(即json/xml/yaml)
【讨论】:
是的!经过三天的头撞墙后,我终于得到了结果!谢谢!【参考方案3】:不确定它是否是您想要的,但您可以通过模型加载它,例如:
var oneperson = new Person(id: anId);
使用存储时,您总是必须发送一个数组,即使它只有一条记录。 我不知道为什么在你的应用程序中总是发送一个数组是有问题的,但它应该很简单,只需强制参数是一个数组......
persons = [*persons]
【讨论】:
我不需要在模型中指定代理才能以您提到的方式加载一个人吗?这对我来说是有问题的,因为默认情况下使单个资源显示为数组不是 RESTful 并且它弄乱了我的 json API... 抱歉,是的,您必须在模型中设置代理。我看到你在 RESTful 上的去向,你不能使用返回许多模型的动作吗? (例如索引)。这里的问题是存储用于处理许多记录,因此将其指向仅返回一条记录的 RESTful url 是不合逻辑的(即:显示操作) 好的——你能发布一个在模型中使用单一资源和代理的例子吗?这对我真的很有帮助(这就是我现在正在尝试做的......)我认为这就是我需要的 只需将代理的配置从商店移动到模型,它应该可以工作。 我无法让它工作,因为它仍然需要一个数组。就个人而言,我不认为这是可能的......我最终在我的服务器端添加了一个新的响应者类型。如果您有更好的解决方案,我很乐意听到。仅供参考 - 我尝试使用: Ext.ModelMgr.getModel('Person').load(123, success: function(person) console.log(person.getId()); );【参考方案4】:我同意 iwiznia,Ext.data.Store 总是等待 [...] 响应,并且您可能应该更改服务器端代码以返回人员数组。 也许您还应该尝试在服务器端和客户端代码中使用 REST 风格的引入。
【讨论】:
以上是关于将单个对象加载到 sencha touch 中的数据存储中的主要内容,如果未能解决你的问题,请参考以下文章
添加处理程序到文档事件将范围更改为 Sencha Touch 中的文档
使用 store sencha touch 2 将数据加载到 List
使用 store Sencha Touch 2 将数据加载到列表中并且不出现