带有 REST API 的可编辑 jQuery Grid 推荐
Posted
技术标签:
【中文标题】带有 REST API 的可编辑 jQuery Grid 推荐【英文标题】:Editable jQuery Grid Recommendations with REST API 【发布时间】:2012-05-30 18:04:56 【问题描述】:首先,我已经阅读了问题“jQuery Grid Recommendations”,但它没有回答我的问题。
我有一个小的REST API with MongoDB Backend 只是:
获得所有装备:
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 用户添加/查看/删除设备。所以我认为带有类似 UI 的 jQuery 的 Web 界面是最好的。我tried 和Sencha Rest Proxy 但我不知道javascript,我无法适应这个例子。
如何为我的 REST 后端修复我的 javascript?
与/或
您能否推荐一个更简单的 Sencha Rest Proxy 替代方案?(适用于我的 REST 后端)
答案: jqGrid
与/或
你会推荐我什么 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/<filename:path>')
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:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Rest Proxy Example</title>
<link rel="stylesheet" type="text/css" href="/static/css/ui.jqgrid.css" />
<link rel="stylesheet" type="text/css" href="/static/css/jquery-ui-1.8.20.custom.css" />
<script type="text/javascript" src="/static/js/jquery.js"></script>
<script type="text/javascript" src="/static/js/jquery.jqGrid.min.js"></script>
<script type="text/javascript" src="/static/js/grid.locale-fr.js"></script>
<script type="text/javascript">
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);
);
</script>
</head>
<body>
<table id="list2"></table>
<div id="pager2"></div>
<br />
</body>
</html>
【问题讨论】:
"我不知道 javascript" - 如果您尝试为 REST 客户端制作前端,那将不得不改变。花时间学习 JavaScript;它最终会得到回报,而且它不是一门很难的语言。 仅供内部团队使用,编写Web前端不是我的工作。有一天,我会学习javascript。但是现在,我有很多更重要的东西。 【参考方案1】:您可以使用 jqGrid 与您的 RESTfull 服务进行通信。 jqGrid 支持树形编辑模式:单元格编辑、内联编辑和表单编辑。此外,内联编辑可以以不同的方式初始化。例如,可以在onSelectRow
或ondblClickRow
回调中调用editRow 方法,或者使用navGrid 在navigator 工具栏中添加“删除”按钮,使用inlineNav 添加“添加”和“编辑”按钮.另一种方法是使用formatter: "actions" 在网格的一列中包含“编辑”按钮。您可以在the official jqGrid demo 中找到所有方法。更多技术实现细节可以在the answer找到。
我个人认为了解在 Web 前端使用 RESTfull 服务的另一个重要方面非常重要。问题是标准的 RESTfull API 没有任何用于数据排序、分页和过滤的标准接口。我试着解释下面的问题。在那之后,我希望 我的建议是明确的,即使用具有附加参数并提供排序、分页和过滤功能的附加方法来扩展当前的标准 RESTfull API。。
如果您有大型数据集,这个问题很容易理解。例如,一次在网格中显示 10000 行数据是没有意义的。如果没有scolling 或paging 数据,用户将无法在屏幕上看到数据。此外,出于同样的原因,实现数据的排序甚至过滤也是有意义的。因此,在开始时只显示一页数据并为用户提供一些数据分页界面更为实用。在 jqGrid 的标准 pager 中看起来像
用户可以转到“下一个”、“最后一个”、“上一个”或“第一个”页面或选择页面大小:
此外,用户可以通过直接输入新页面并按Enter来指定所需的页面:
同理,用户可以点击任意一列的表头,按列对网格数据进行排序:
另一个非常重要的用户界面元素(从用户的角度来看很重要)可能是一些过滤界面,例如 here 或搜索界面,例如 here。
我给你一个来自 jqGrid 的例子,但我发现这个问题很常见。 我想强调的是,RESTfull 服务没有为您提供对数据进行排序、分页和过滤的标准接口。
在使用 jqGrid 的情况下,RESTfull url 将默认获取 附加 参数。它是:page
、rows
指定将从服务中询问的页码和页面大小、sidx
和 sord
指定排序列和排序方向的参数以及 _search
和 @987654346 @(最后一个在the format)允许支持过滤。如果需要,可以使用 jqGrid 的prmNames 选项重命名参数。
我建议您阅读the answer 关于 URL 编码的问题。我认为 _search=false&rows=20&page=1&sidx=&sord=asc
部分不属于资源,因此最好将信息作为 parameters 而不是作为 URL 的一部分发送。
我在回答中主要想表达的是,纯经典 RESTfull API 的使用不足以实现良好的用户界面。您将不得不使用用于分页、排序和过滤的附加参数来扩展界面,否则您将无法创建高性能和用户友好的 Web GUI。
【讨论】:
感谢您这么长的回答。有点它没有回答我的问题:事实上,不可能将 jQGrid 与我的 REST 后端一起使用。 jQGrid 使用特定的 jsojn 格式: total: xxx, page: yyy, records: zzz, rows: [ name1:”Row01″,name2:”Row 11″,name3:”Row 12″,name4:”Row 13″,name5:”Row 14″, ...
@Yohann:不! jqGrid 几乎可以读取任何 JSON 格式,您只需使用相应的jsonReader。您没有详细描述您当前的数据格式,但我认为以下jsonReader
将适用于您的情况: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;
@Yohann: 输入数据的标准格式看起来有点奇怪,但是如果你从服务器的字符串数组而不是 named 属性发送你可以减少数据的大小在服务器和客户端之间传输。此外,它要求用户指定每一行的唯一 id
,因为id 将用作<tr>
的id
- rowid。
谢谢!现在,我只需要修复一些 javascript 即可拥有可编辑的单元格!
@Yohann:不客气!您应该选择最符合您要求的编辑模式。以上是关于带有 REST API 的可编辑 jQuery Grid 推荐的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法使用 Django REST 框架中的可浏览 API 上传文件?
用于银行交易中预期目的的带有自定义发票编号的 PayPal Rest API 付款
如何在 C# Rest API 中处理查询参数中的可选 ENUM - 无效和空值以及在 Swagger 中隐藏特定值