ExtJS存储器失败

3

ExtJS模型字段有映射选项。

fields: [
        {name: 'brandId', mapping:'brand.id',   type: 'int'},
        {name: 'brandName', mapping:'brand.name', type: 'string'},

问题是:如果服务器响应不包含某些字段(例如我的示例中的品牌字段),并且定义了内部字段的映射,则Ext Store会默默地无法加载任何记录。
有人遇到这个问题吗?这是一种错误吗?
更新: 为了让它更清楚:假设我的模型有十个字段。来自服务器的响应有九个字段,缺少一个字段。如果此字段没有嵌套映射(mapping:'x.y.z'),则一切正常-存储器加载记录,该字段为空。但是,如果必须从某个嵌套字段加载此字段并具有映射选项,则存储器将无法加载任何内容。
更新2: 我已经找到了引起问题的代码。事实是:当Ext尝试从Json加载某个字段时,它执行以下检查
(source["id"] === undefined) ? __field0.defaultValue : source["id"]

当字段有映射选项(mapping 'brand.id')时,阅读器会以以下方式进行

(source.brand.id === undefined) ? __field20.defaultValue : source.brand.id

如果源数据没有品牌字段,会导致错误。

如果您遇到同样的问题,您可以通过重载Ext.data.reader.Json的方法createFieldAccessExpression来解决它。


如果存储在响应中找不到记录,您还期望发生什么其他行为?我的意思是,您对此行为有何问题? - Jean-Francois Hamelin
好的,这条记录来自服务器,只是没有“品牌”字段。如果一条记录缺少某个字段而且没有映射,一切都没问题,存储加载记录,该字段为空。 - mik
(在我的例子中)你没有显示品牌字段。你只有品牌ID和品牌名称。请澄清一下。 - Jere
模型中没有品牌字段,但是服务器响应中应该有品牌字段 "brand":{"id":"1","name":"Hyundai"} 我说得清楚吗? - mik
“Store 静默失败加载任何记录”只是因为它无法确定服务器上 brand 的实际数据(响应中未接收到 brand),因此 Store 无法获取 brand.idbrand.name。如果无法确定 brand,那么 Store 如何知道是否已更改此字段以与服务器上的实际数据进行比较以进行更新。因此,在这种情况下,事件处理将是不可能的。 - U and me
我不同意。当字段上没有定义映射并且该字段在服务器响应中丢失时,store 仍然可以完美地加载记录。你如何解释这个现象? - mik
2个回答

2

我认为Ext应该只是加载失败该字段,而不是整个记录。一个并不完美但可行的选择是使用一个mapping函数:

{
    name: 'brandId',
    mapping: function(data, record) {
        return data.brand && data.brand.id;
    }
}

我可能把参数搞错了(我是通过查看源代码发现这个功能的),所以如果它不像这样工作,可以在那里设置断点以查看可用的内容。


FYI,这是一项设计决策,数据读取可能非常缓慢,因此必须在使用某些“复杂”的JSON表达式时,在try-catch块中进行处理并不理想。 - Evan Trimboli
或许 Ext 可以做到我在这个回复中所做的事情,即使用“&&”分隔的点路径,这样如果它不存在,你会得到 false - Sean Adkinson
好主意,BigSean。但我选择了“try ... catch ...”块。 - mik

0

我认为你误解了映射(mapping)嵌套(nesting)的范例:它们并不是可以互换的。 如果你在数据中定义了嵌套,那么结果必须具有相应的字段。


是的,事实证明它是这样工作的,但文档上并没有提到,我认为这是错误的行为。 - mik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接