I'm trying to load a single json object using sencha touch. When I work with arrays, all is well, but I havn't find a way of loading a single object into an Ext.data.Store
here is a sample of what I'm trying to load:
{"person":{"name":"John","surname":"Fox"}}
and it's not working. after looking at this entry,
I tried to load the following and it worked:
[{"person":{"name":"John","surname":"Fox"}}]
My questions is: is there a way of loading it w/o the [ ]? I had to modify my server side code in order to do this and it feels to me like a code smell... I want to be able to load a single json object w/o putting it into a list.
here is my Sencha Touch pro开发者_运维技巧xy code:
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'
}
}
});
BTW - my server side code is in Ruby on Rails.
Animal from the Ext Development Team has given this very useful solution:
reader: {
type: 'json',
root: function(data) {
if (data.users) {
if (data.users instanceof Array) {
return data.users;
} else {
return [data.users];
}
}
}
}
By simply using a function as root, you can make sure the reader gets the object in an array.
update: the way to access a single json object using sencha is just to make a simple request and not use a data store. here is an example of code that does this:
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...');
}
});
If you still insist on using a dataStore - here is a possible solution in the server side that maintains a restful API: here is what I did in order to keep my API restful:
I added a new MIME type called sencha, that behaves exactly like json but it also wraps the json in [ ] parenthesis.
It might be (and probably is) an overkill, but this way it's not intrusive to my JSON API. here is the code for the new MIME type:
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
this allows me to define the following proxy (notice the format: 'sencha' ) in the client side:
proxy: {
type: 'rest',
format: 'sencha',
url : my server url,
reader: {
type: 'json',
record: 'person'
}
}
This way I can still keep a restful API, and regard Sencha's json representation as another way of representing resources (i.e. json/xml/yaml)
Not sure if it's what you want, but you can load it through the model like:
var oneperson = new Person({id: anId});
When using a store you always have to send an array, even if it only has one record in it. I don't know why always sending an array is problematic in your application, but it should be prette simple, just force the parameter to be an array...
persons = [*persons]
I agree with iwiznia, Ext.data.Store always waits for a [...] response, and probably you should change serverside code to return array of persons.
Maybe you should also try to use REST style intraction of your serverside and client code.
精彩评论