使用REST API编辑可编辑的jQuery Grid Recommendations

首先,我已经阅读了“ jQuery Grid Recommendations ”这个问题,但它没有回答我的问题。

我有一个与MongoDB后端的小型REST API :

获得所有设备:

GET /equipements HTTP/1.1 {{_id:key1, name:Test Document 1, plateforme:prod}, {_id:key2, name:Test Document 2, plateforme:prod}, ...} 

使用密钥获取设备:key1

 GET /equipements/key1 HTTP/1.1 {"_id": "key1", "name": "Test Document 1", "plateforme": "prod"} 

添加新设备

 PUT /equipements HTTP/1.1 {"_id": "key8", "name": "Test Document 3", "plateforme": "prod"} HTTP/1.0 200 OK 

现在,我需要找到一种简单的方法来允许lambda用户添加/查看/ del设备。 所以我认为一个像UI这样的jQuery的Web界面是最好的。 我尝试使用Sencha Rest Proxy,但我不知道javascript,我无法适应这个例子。

如何修复我的REST后端的JavaScript?

AND / OR

你能推荐一个比Sencha Rest Proxy更简单的替代品吗? (适用于我的REST后端)

答案: jqGrid

AND / OR

你会推荐我什么jQuery Grid? (适用于我的REST后端)

答案: jqGrid

最后一个问题 :为什么双击时我的单元格不可编辑?

附录

服务器端(编辑:添加方法POST)

 #!/usr/bin/python import json import bottle from bottle import static_file, route, run, request, abort, response import simplejson import pymongo from pymongo import Connection import datetime class MongoEncoder(simplejson.JSONEncoder): def default(self, obj): # convert all iterables to lists if hasattr(obj, '__iter__'): return list(obj) # convert cursors to lists elif isinstance(obj, pymongo.cursor.Cursor): return list(obj) # convert ObjectId to string elif isinstance(obj, pymongo.objectid.ObjectId): return unicode(obj) # dereference DBRef elif isinstance(obj, pymongo.dbref.DBRef): return db.dereference(obj) # convert dates to strings elif isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) or isinstance(obj, datetime.time): return unicode(obj) return simplejson.JSONEncoder.default(self, obj) connection = Connection('localhost', 27017) db = connection.mydatabase @route('/static/') def send_static(filename): return static_file(filename, root='/home/igs/restlite/static') @route('/') def send_static(): return static_file('index.html',root='/home/igs/restlite/static/') @route('/equipements', method='PUT') def put_equipement(): data = request.body.readline() if not data: abort(400, 'No data received') entity = json.loads(data) if not entity.has_key('_id'): abort(400,'No _id specified') try: db['equipements'].save(entity) except ValidationError as ve: abort(400, str(ve)) @route('/equipements', method='POST') def post_equipement(): data = request.forms if not data: abort(400, 'No data received') entity = {} for k,v in data.items(): entity[k]=v if not entity.has_key('_id'): abort(400,'No _id specified') try: db['equipements'].save(entity) except ValidationError as ve: abort(400, str(ve)) @route('/equipements/:id', methodd='GET') def get_equipement(id): entity = db['equipements'].find_one({'_id':id}) if not entity: abort(404, 'No equipement with id %s' % id) return entity @route('/equipements', methodd='GET') def get_equipements(): entity = db['equipements'].find({}) if not entity: abort(404, 'No equipement') response.content_type = 'application/json' entries = [entry for entry in entity] return MongoEncoder().encode(entries) run(host='0.0.0.0', port=80) 

编辑:JQGrid:

     Rest Proxy Example       jQuery(document).ready(function(){ var lastsel; jQuery("#list2").jqGrid({ url:'equipements', datatype: "json", colNames:['Id','Name', 'Plateforme'], colModel:[ {name:'_id',index:'_id', width:50, editable:true}, {name:'name',index:'_id', width:300, editable:true}, {name:'plateforme',index:'total', width:200,align:"right", editable:true}, ], rowNum:30, rowList:[10,20,30], pager:'pager2', sortname: '_id', viewrecords: true, width: 600, height: "100%", sortorder: "desc", onSelectRow: function(_id){ if(_id && _id!==lastsel){ jQuery('#liste2').jqGrid('restoreRow',lastsel); jQuery('#liste2').jqGrid('editRow',_id,true); lastsel=_id; } }, jsonReader: { repeatitems: false, id: "_id", root: function (obj) { return obj; }, records: function (obj) { return obj.length; }, page: function (obj) { return 1; }, total: function (obj) { return 1; } }, editurl:'equipements', caption:"Equipements" }); jQuery("#list2").jqGrid('navGrid','#pager2',{edit:true,add:true,del:true}); });    

您可以使用jqGrid与RESTfull服务进行通信。 jqGrid支持树编辑模式:单元格编辑,内联编辑和表单编辑。 此外,可以以不同方式初始化内联编辑。 例如,可以在onSelectRowondblClickRow回调中调用editRow方法,或使用navGrid在导航器工具栏和inlineNav中添加“删除”按钮以添加“添加”和“编辑”按钮。 另一种方法是使用格式化程序:“动作”在网格的一列中包含“编辑”按钮。 您可以在官方的jqGrid演示中找到所有方法。 您可以在答案中找到更多技术实现细节。

我个人认为您了解在Web前端使用RESTfull服务的另一个重要方面非常重要。 问题是标准RESTfull API没有任何标准接口用于数据的排序,分页和过滤。 我试着解释下面的问题。 在此之后,我希望我的建议是使用附加方法扩展当前标准RESTfull API,并提供排序,分页和过滤function

如果您有大型数据集,则很容易理解该问题。 没有意义在网格中一次显示10000行数据。 如果没有数据的搜索分页 ,用户将无法在屏幕上看到数据。 此外,由于相同的原因,有意义的是实现排序甚至过滤数据。 因此,在开头只显示一页数据并为用户提供一些用于分页数据的界面更加实用。 在jqGrid的标准寻呼机中看起来像

在此处输入图像描述

用户可以转到“下一页”,“上一页”,“上一页”或“第一页”页面或选择页面大小:

在此处输入图像描述

此外,用户可以通过直接输入新页面并按Enter键来指定所需页面:

在此处输入图像描述

以同样的方式,用户可以单击任何列的标题,按列对网格数据进行排序:

在此处输入图像描述

另一个非常重要的用户界面元素(从用户的角度来看很重要)可以是一些过滤界面,例如像这里一样的搜索界面。

我给你jqGrid的例子,但我发现问题很常见。 我想强调的是,RESTfull服务不为您提供排序,分页和过滤数据的标准接口

在使用jqGrid的情况下,RESTfull url将默认获得其他参数。 它是: page ,指定页面编号的rows和将从服务中提出的页面大小, sidxsord参数指定排序列和排序方向以及_searchfilters (最后一种是格式 )允许支持过滤。 如果需要,可以使用jqGrid的prmNames选项重命名参数。

我建议您阅读有关URL编码问题的答案 。 我认为部分_search=false&rows=20&page=1&sidx=&sord=asc不属于资源,因此最好将信息作为参数发送,而不是作为URL的一部分发送。

我在答案中主要想表达的是纯粹的经典RESTfull API的使用不足以实现良好的用户界面。 您将不得不使用用于分页,排序和过滤的其他参数扩展接口,否则您将无法创建高性能和用户友好的Web GUI。