ExtJS:当服务器响应简单成功时,Model.save()错误“无法读取未定义的属性'数据'

时间:2011-10-24 22:58:24

标签: extjs4

(ExtJS 4.0.7)

我正在使用Model.save()来更新服务器。一切正常,服务器返回一个简单的JSON响应{success: true}(HTTP状态200)。但是,Model.save()会抛出以下错误:

Uncaught TypeError: Cannot read property 'data' of undefined

以下是ExtJS代码(src / data / Model.js)中发生的情况:

save: function(options) {
   ...
   callback = function(operation) {
      if (operation.wasSuccessful()) {
         record = operation.getRecords()[0]; <-- getRecords() return an empty array
         me.set(record.data); <-- record is undefined, so .data causes error
   ...
}

我已经发现这种情况正在发生,因为Model.save()希望服务器使用JSON响应刚刚更新(或创建)的整个对象。

当服务器以简单的成功消息响应时,是否有人知道一种聪明的方法使Model.save()工作?

2 个答案:

答案 0 :(得分:1)

我能够通过为模型使用自定义代理并覆盖update函数来解决问题:

Ext.define('kpc.util.CustomRestProxy', {
    extend: 'Ext.data.proxy.Rest',
    alias: 'proxy.kpc.util.CustomRestProxy',
    type: 'rest',

    reader : {
        root: 'data',
        type: 'json',
        messageProperty: 'message'
    },

    // Model.save() will call this function, passing in its own callback
    update: function(operation, callback, scope) {

        // Wrap the callback from Model.save() with our own logic
        var mycallback = function(oper) {
            // Delete the resultSet from the operation before letting
            // Model.save's callback use it; this will 
            oper.resultSet = undefined;
            callback(op);
        };

        return this.doRequest(operation, mycallback, scope);
    }
});

简而言之,当我的代理被要求进行更新时,它确保operation.resultSet == undefined。这会更改operation.getRecords()的返回值(您可以在我的问题的代码示例中看到)。这是函数的样子(src / data / Operation.js):

getRecords: function() {
    var resultSet = this.getResultSet();
    return (resultSet === undefined ? this.records : resultSet.records);
}

通过确保resultSet == undefined,operation.getRecords返回模型的当前数据而不是空结果集(因为服务器没有返回结果,只返回简单的成功消息)。因此,当save()中定义的回调运行时,模型会将其数据设置为其当前数据。

答案 1 :(得分:0)

我调查了这个问题并找到了真正简单的答案。你的结果必须是这样的:

{
  success: true,
  items: { id: '', otherOpt: '' }
}

并且items属性必须等于Model->Reader->root属性(例如树中的子项)。

如果您想使用项目代替子项,您可以在Store中使用defaultRootProperty属性并根据需要配置嵌套集合。

PS

items in items属性必须完全定义,因为它取代了商店中的实际记录。