2011-10-30 111 views
2
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' 
     } 
    } 
}); 

我有這家店的定義,我想在一個網格編輯器插件使用它:如果我輸入有效的數據ExtJS的4 CRUD服務器端驗證

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

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

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'] 
    } 
}