我有你的問題的部分解決方案。我在代理中創建了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工作樣本。