首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ExtJS 4-包含没有Id关系的其他模型的模型

ExtJS 4-包含没有Id关系的其他模型的模型
EN

Stack Overflow用户
提问于 2014-02-25 10:37:58
回答 1查看 603关注 0票数 2

给定的是这样的嵌套模型结构:

代码语言:javascript
复制
Model Website
 + id
 + name
 + images[] // List of Image instances

Model Image
 + imageName
 + imageUrl

响应的序列化版本如下:

代码语言:javascript
复制
{
 "id": 4711,
 "name": "Some name",
 "images" [
  {"imageName": "Beach", "imageUrl": "http://example.com/whatever.jpg"},
  ...
 ]
}

此嵌套模型集将持久化在文档存储中,并根据Website.id的请求返回。

不存在与嵌套的图像列表的id-关系,因为它们作为一个列表直接保存在父模型中。据我所知,Ext.data.Model中的经典关系是指通过一个id-关系建立的相关模型。

问题是:我是否可以告诉父模型对它的图像列表中的每个孩子使用图像模型?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-25 12:38:58

作为第一步,您可以使用字段类型的auto将图像数据加载到模型中。

代码语言:javascript
复制
Ext.define('My.Model', {
    extend: 'Ext.data.Model'

    ,fields: [
        {name: 'images', type: 'auto'}
        // ... other fields
    }
});

然后:

代码语言:javascript
复制
myModel.get('images');

应返回:

代码语言:javascript
复制
[
    {"imageName": "Beach", "imageUrl": "http://example.com/whatever.jpg"},
    ...
]

从理论上讲,您应该能够实现一个完全自动化的解决方案,从这些数据创建模型,并且--最困难的部分--尝试保持这些创建的记录和父模型中的子数据保持同步。但是这是一次非常复杂的黑客攻击,而且Ext代码库中的许多入口点都必须包括在内。作为一个例子,我曾经试图这样做,因为“有一个”关系,并代表很多代码。因此,我从未花时间来合并这段代码,最后也从未使用过它。

我更愿意提倡一种简单和局部的解决方案(针对模型)。您可以添加一个简单的方法到您的模型,以获取图像作为记录。例如:

代码语言:javascript
复制
Ext.define('My.Model', {

    // ...

    ,getImages: function() {
        var store = this.imageStore;
        if (!store) {
            store = new Ext.data.Store({
                model: 'My.ImageModel'
                ,data: this.get('images') || []
            });
            this.imageStore = store;
        }
        return store;
    } 
});

为相关模型创建一个存储区可以避免使用代理和读取器。它还为您提供了一个与Ext默认的关联界面相近的接口。

如果需要对同一父记录多次加载映像的支持,则可以挂起该字段的convert方法。

最后,您还可能需要处理关联数据的客户端修改,以便能够将它们保存到服务器上。如果关联模型允许,您可以简单地使用子存储的sync方法(并且不要忘记在同步回调中更新父模型的数据!)但是,如果关联模型没有连接到服务器端的端点,则应该能够挂起serialize方法来保存关联存储中的数据(与存储在父记录中的数据相反,如果使用关联存储区,则不会更新数据)。

下面是最后一个示例,展示了这两种情况:

代码语言:javascript
复制
Ext.define('My.Model', {
    extend: 'Ext.data.Model'

    ,fields: [
        {
            name: 'images'
            ,type: 'auto'

            // enables associated data update
            ,convert: function(data) {
                var store = this.imageStore;
                if (store) {
                    store.loadData(data || []);
                }
                return data;
            }

            // enables saving data from the associated store
            ,serialize: function(value, record) {
                var store = record.imageStore,
                if (store) {
                    // care, the proxy we want is the associated model's one
                    var writer = store.proxy && store.proxy.writer;
                    if (writer) {
                        return Ext.Array.map(store.getRange(), function(record) {
                            return writer.getRecordData(record);
                        });
                    } else {
                        // gross implementation, simply use the records data object
                        return Ext.pluck(store.getRange(), 'data');
                    }
                } else {
                    return record.get('images');
                }
            }
        }

        // ... other fields
    }

    ,getImages: function() {
        var store = this.imageStore;
        if (!store) {
            store = new Ext.data.Store({
                model: 'My.ImageModel'
                ,data: this.get('images') || []
            });
            this.imageStore = store;
        }
        return store;
    } 
});

请注意,我还没有测试这段代码,所以它可能仍然包含一些错误.但我希望这足以给你一个大致的想法!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22011602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档