如何使用qx.data.store.Json

如何使用qx.data.store.Json,json,qooxdoo,Json,Qooxdoo,我想知道如何准确地使用qx.data.store.Json-store。 在我的例子中,我在Web服务中实现了以下方法: getUser 地址用户 删除用户 添加文档 获取文档 删除文档 我现在的问题是:我必须从qx.data.store.Json创建一个存储扩展并实现这个方法吗 比如: 或者我应该为上述所有方法使用原始的qx.data.store.Json吗? 比如: 在第二种情况下,我必须再次为每个请求创建存储,并使其f.e.异步 Tobiasqx.data.store.Json仅从服务器获

我想知道如何准确地使用qx.data.store.Json-store。 在我的例子中,我在Web服务中实现了以下方法:

getUser 地址用户 删除用户 添加文档 获取文档 删除文档 我现在的问题是:我必须从qx.data.store.Json创建一个存储扩展并实现这个方法吗 比如:

或者我应该为上述所有方法使用原始的qx.data.store.Json吗? 比如:

在第二种情况下,我必须再次为每个请求创建存储,并使其f.e.异步

Tobias

qx.data.store.Json仅从服务器获取数据。我不知道如何使用qx.data.store.Json实现addUser或deleteUser-无法在存储内部使用的Xhr上设置请求数据。来自qooxdoo手册:store组件的主要用途是从源加载数据并将该数据转换为模型。没有关于写回服务器的内容-事实上,唯一显式读写存储是脱机存储-它使用本地存储

如果我正确理解了您的问题,您需要使用qx.io.rest.Resource来获取、添加和删除服务器上的用户和文档,可能还需要更新用户和文档。这样,您就可以将URL和http谓词的组合映射到用户和文档上的服务器端操作。这还允许您设置要发送的数据,以便执行添加和更新等操作。您可以通过侦听资源本身上的成功事件来获取对资源调用的异步操作返回的数据—响应中的任何数据都将位于事件的data属性中

然后,您可以通过qx.data.marshal.JSON将事件中包含的JSON自动转换为qooxdoo对象,然后将生成的模型设置为控制器的模型属性。它将创建与qx.data.store中的存储相同类型的类。

是只读存储实现。它只设置其model属性,该属性的值是从JSON转换而来的,并从传递给其构造函数的URL中检索。通常,在Qooxdoo数据层设计中,所有连接都是双向的

可以通过子类化qx.data.store.JSON来实现读写JSON存储。其模型为标准Qooxdoo数据对象。您可以绑定到它,您可以监听它的更改,存储创建带有冒泡更改的模型,等等

下面是列表控制器的示例,它的模型是。其更改事件具有类型add、remove和others。因此,当模型发生更改时,您可以发出相应的请求。后端是虚拟RPC的CherryPy应用程序。请注意,这是一个演示代码,它不处理请求对象、侦听失败事件以及在实际代码中应该执行的其他操作

JsonStore.js

Application.js

app.py


这是演示用的。另外,在高级绑定到qx.data.Array的情况下,请注意团队不会急于修复的问题。用户代码修复。

谢谢你的回答,但我认为你是不对的。可以通过委托向Xhr对象添加数据,但对于简单的Post/Put/Delete来说,这似乎有点复杂。请参见此示例:右-您可以使用.reload/.setUrl与委托组合来实现所需的功能。但我同意这不好——当调用它时,代理需要知道发生了什么。
var store = new myapp.store.MyJsonStore(url);
var user = store.getUser("testuser");
var store = new qx.data.store.Json("http://localhost:1234/users/testuser");
var user = store.getModel();
qx.Class.define('adhoc.JsonStore', {

  extend : qx.data.store.Json,

  construct : function(baseUrl, delegate)
  {
    this.base(arguments, baseUrl + '/list', delegate);

    this._baseUrl = baseUrl;

    // can't refine model property to set apply method because
    // it has not init value
    this.addListener('changeModel', this._onChangeModel, this);
  },

  members : {

    _baseUrl : null,


    _create : function(entry)
    {
      var request = new qx.io.request.Xhr(this._baseUrl + '/create');
      request.setAccept('application/json');
      request.setParser('json');
      request.setRequestData(qx.util.Serializer.toNativeObject(entry));
      request.addListener('success', this.reload, this);
      request.send();
    },

    _remove : function(entry)
    {
      var request = new qx.io.request.Xhr(this._baseUrl + '/remove');
      request.setAccept('application/json');
      request.setParser('json');
      request.setRequestData({'id': entry.getId()});
      request.send();      
    },

    _onChagneModelDataArray : function(event)
    {
      var change = event.getData();
      if(change.type == 'add')
      {
        this._create(change.added[0]);
      }
      else if(change.type == 'remove')
      {
        this._remove(change.removed[0]);
      }
    },

    _onChangeModel : function(event)
    {
      var model = event.getData();
      model.addListener('change', this._onChagneModelDataArray, this);
    }

  }

});
qx.Class.define('adhoc.Application', {

  extend : qx.application.Standalone,

  members : {

    main : function()
    {
      this.base(arguments);

      if(qx.core.Environment.get('qx.debug'))
      {
        qx.log.appender.Native;
        qx.log.appender.Console;
      }


      var list = new qx.ui.form.List();
      list.setWidth(120);

      var controller = new qx.data.controller.List(null, list);
      controller.setLabelPath('name');
      controller.setLabelOptions({'converter': function(value, model) 
      {
        return model.getId() + ':' + value;
      }});

      var store = new adhoc.JsonStore('/document');
      store.bind('model', controller, 'model');


      var create = new qx.ui.form.Button('Create');
      create.addListener('execute', function()
      {
        var name = window.prompt('Enter document name');
        if(name)
        {
          controller.getModel().push(qx.data.marshal.Json.createModel({
            'id'   : null,
            'name' : name
          }));
        }
      });

      var remove = new qx.ui.form.Button('Remove');
      controller.bind('selection[0]', remove, 'enabled',{'converter':Boolean});
      remove.addListener('execute', function()
      {
        var confirmed = window.confirm('Remove selected document?');
        if(confirmed)
        {
          controller.getModel().remove(controller.getSelection().getItem(0));
        }
      });


      var root = this.getRoot();
      root.add(create, {'left': 10, 'top': 10});
      root.add(remove, {'left': 70, 'top': 10});
      root.add(list,   {'left': 10, 'top': 40});
    }

  }

});
#!/usr/bin/env python
# -*- coding: utf-8 -*-


import os

import cherrypy


path   = os.path.abspath(os.path.dirname(__file__))
config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  },
  '/static' : {
    'tools.staticdir.on'  : True,
    'tools.staticdir.dir' : os.path.join(path, 'qxjsonstore')
  }  
}


class Document:

  _store = None


  def __init__(self):
    self._store = {
      1 : {'id': 1, 'name': 'foo'},
      2 : {'id': 2, 'name': 'bar'},
      3 : {'id': 3, 'name': 'baz'},
      4 : {'id': 4, 'name': 'qux'},
    }

  @cherrypy.expose
  @cherrypy.tools.json_out()
  def list(self):
    return self._store.values()

  @cherrypy.expose
  @cherrypy.tools.json_out()
  def create(self, **kwargs):
    id = max(self._store.keys()) + 1
    self._store[id] = {'id': id, 'name': kwargs['name']}
    return id

  @cherrypy.expose
  @cherrypy.tools.json_out()
  def remove(self, id):
    del self._store[int(id)]


class App:

  document = None


  def __init__(self):
    self.document = Document()

  @cherrypy.expose
  def index(self):
    return '''<!DOCTYPE html>
      <html>
      <head>
        <!-- Demo is built on qx.js from the framework's build-all job. 
             Do not use it in real application because it includes all
             Qooxdoo classes.
        -->
        <script type="text/javascript">
          var qx = {};
          qx.$$environment = {"qx.application": "adhoc.Application"};
        </script>
        <script type="text/javascript" src="/static/qx.js"></script>
        <script type="text/javascript" src="/static/app.js"></script>
      </head>
      <body></body>
      </html>
    '''


if __name__ == '__main__':
  cherrypy.quickstart(App(), '/', config)