【问题标题】:load single object into a data store in sencha touch将单个对象加载到 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 中。

【问题讨论】:

    标签: javascript ruby-on-rails json sencha-touch extjs


    【解决方案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 风格的引入。

      【讨论】:

        猜你喜欢
        • 2012-01-15
        • 2013-08-30
        • 1970-01-01
        • 1970-01-01
        • 2012-07-24
        • 1970-01-01
        • 2013-05-03
        • 1970-01-01
        • 2023-03-29
        相关资源
        最近更新 更多