Ext.define('Workshop.store.WorkType',
{
extend: 'Ext.data.Store',
model: 'Workshop.model.WorkType',
autoLoad: true,
autoSync: true,
pageSize: 25,
proxy:
{
type: 'ajax',
api:
{
read: '/ajax_js.php?func=WorkType::selectRow',
update: '/ajax_js.php?func=WorkType::updateRow',
create: '/ajax_js.php?func=WorkType::insertRow',
destroy: '/ajax_js.php?func=WorkType::deleteRow'
},
reader:
{
type: 'json',
root: 'root',
successProperty: 'success',
totalProperty: 'totalCount'
}
}
});
我有这个商店定义,我想在带有编辑器插件的网格中使用它:
Ext.define('Ext.ux.EditorGrid',
{
extend: 'Ext.grid.Panel',
plugins:
[
Ext.create('Ext.grid.plugin.RowEditing',
{
clicksToEdit: 2
})
],
store: Ext.create('Workshop.store.WorkType'),
border: false,
columns:
[
{header: trans.translate('WORKTYPENAME'), dataIndex: 'name', flex: 1, editor: 'textfield'},
{header: trans.translate('FACTOR'), dataIndex: 'factor', flex: 1, editor: 'textfield'}
]
});
如果输入有效数据,一切正常,但如果服务器验证失败,该怎么办? 如何才能实现标记并且编辑器不会关闭?
这也可用于新的记录插入,如何验证新数据?
答案 0 :(得分:2)
这是我为演示项目做的快速黑客攻击:
下面是rowedit插件的监听器哈希
listeners: {
canceledit: function(editor, e, options) {
if (e.record.phantom) {
return e.grid.store.remove(e.record);
}
},
edit: function(editor, e) {
var ed, grid;
ed = editor;
grid = editor.cmp;
grid.el.mask('Loading ...', 'x-loading');
return e.record.save({
success: function(record, operation) {
return grid.el.unmask();
},
failure: function(record, operation) {
grid.el.unmask();
ed.startEdit(grid.store.indexOf(record), 0);
return Ext.Object.each(operation.request.proxy.reader.jsonData.errors, function(field, errors) {
return ed.editor.down("[name=" + field + "]").markInvalid(errors);
});
}
});
}
}
服务器应该返回这样的响应:
{
success: false,
errors: {
field1: ['error message1'],
field2: ['error message2', 'error message3']
}
}
答案 1 :(得分:0)
我部分解决了你的问题。我在代理中创建了validate
方法,在保存之前验证数据。这并不容易,但最终它起作用(至少部分地)。它不是很漂亮,但要让这项工作变得非常困难。这应该是在保存时创建验证的良好入口点。代码如下。
// extended RowEditor
Ext.define('Ext.grid.ExtRowEditor', {
extend: 'Ext.grid.RowEditor',
// here we can plugin into editor
onFieldAdd: function(map, fieldId, column) {
this.callParent(arguments);
var plugin = this.editingPlugin;
var editor = column.getEditor();
// if not yet initialized
if (editor._extRowEditorInit === undefined) {
// create interceptor to fire event that will eventually send validation request to the server
editor.validate = Ext.Function.createInterceptor(editor.validate, function() {
this.fireEvent('validationneeded', this, column, plugin);
}, editor);
// create validator
editor.validator = function() {
if (!this.errorValue) {
return true;
}
if (!this.getValue()) {
return true;
}
return (this.errorValue.toString() == this.getValue().toString()) ? this.errorMessage : true;
};
// create validationneeded event handler
editor.on('validationneeded', this.onValidationneeded, this, { buffer: 100 });
// mark initialized
editor._extRowEditorInit = true;
}
},
// send request to server
onValidationneeded: function(editor, column, plugin) {
var context = plugin.context;
var store = context.store;
var record = context.record;
// if nothing changed we don't need to send request
if (record.get(column.dataIndex) === editor.getValue()) {
return;
}
// copy record; at this point original record still has old value, so we must set this from editor
record = new record.store.model(record.data);
record.set(column.dataIndex, editor.getValue());
// create operation
var operation = Ext.create('Ext.data.Operation', {
action : 'validate',
records: [
record
]
});
var scope = { editor: editor, plugin: plugin };
// create handler on exception; there is no way to access exception data from regular doRequest handler
store.proxy.on('exception', function(sender, response, operation, opts) {
// assign error to scope
this.error = Ext.decode(response.responseText);
}, scope, { single: true });
// do request
return store.proxy.doRequest(operation, this.onProxyValidate, scope);
},
// doRequest callback
onProxyValidate: function(operation) {
if (operation.action !== "validate") {
return;
}
// if validation was successful then there is nothing to do
if (this.error == undefined || this.error.success) {
return;
}
var errors = this.error.errors;
var plugin = this.plugin;
var grid = plugin.grid;
// this is private member
var columns = grid.headerCt.getGridColumns();
Ext.each(operation.records, function(record){
Ext.each(errors, function(error) {
// search column by dataIndex
var column = Ext.Array.filter(columns, function(c) { return c.dataIndex == error.dataIndex; })[0];
// get editor
var editor = column.getEditor();
// check if value in editor is still the same
if (editor.getValue().toString() == record.get(column.dataIndex).toString()) {
// set properties on editor, which will be accessed from validator method
editor.errorValue = editor.getValue();
editor.errorMessage = error.message;
// editor.setActiveError(error.message);
}
});
}, this);
plugin.editor.onFieldChange();
}
});
// Extended plugin; only difference is that it creates ExtRowEditor instead of RowEditor
Ext.define('Ext.grid.plugin.ExtRowEditing', {
extend: 'Ext.grid.plugin.RowEditing',
initEditor: function() {
var me = this,
grid = me.grid,
view = me.view,
headerCt = grid.headerCt;
return Ext.create('Ext.grid.ExtRowEditor', {
autoCancel: me.autoCancel,
errorSummary: me.errorSummary,
fields: headerCt.getGridColumns(),
hidden: true,
// keep a reference..
editingPlugin: me,
renderTo: view.el
});
}
});
在代理中,您应该创建validation
方法:
var store = Ext.create('Ext.data.Store', {
proxy: {
type: 'ajax',
api:
{
read: 'api/read.php',
update: 'api/update.php',
create: 'api/create.php',
destroy: 'api/destroy.php',
validate: 'api/validate.php' // validation method
},
reader: {
type: 'json',
root: 'data'
}
}
});
Here正在制作样本。