ExtJS - 如何使用代理,模型?它们有啥关系?
Posted
技术标签:
【中文标题】ExtJS - 如何使用代理,模型?它们有啥关系?【英文标题】:ExtJS - How to use Proxy, Model? How are they related?ExtJS - 如何使用代理,模型?它们有什么关系? 【发布时间】:2011-11-16 07:40:45 【问题描述】:我一直在努力学习如何使用模型和商店。但是代理位让我很困惑。所以我将在这里列出我的理解 - 请指出我的理解中的差距。
我的理解
-
模型用于表示域对象。
模型可以由 ModelManager 创建,也可以简单地使用构造函数来创建
模型保存在商店中
存储可以在内存存储中,也可以是服务器存储。这是使用代理配置的。
代理告诉存储如何与后备存储通信 - 无论是 JSON 数组、REST 资源还是通过 ajax 简单配置的 URL。
商店负责存储模型,代理负责控制/帮助完成该任务。
当模型的值改变时,它的
dirty
标志被设置。保存模型时会自动清除。 (稍后会详细介绍)
让我困惑的部分
-
为什么Model上有
proxy
config和save
方法?我了解模型只能存储在商店中。
为什么当我将模型对象添加到商店时,dirty
标志没有被清除?
当我将模型对象添加到商店时,为什么模型没有获取使用该商店配置的代理?
proxy
是模型的静态配置。这是否意味着我们不能使用具有多个数据源的特定模型的对象?延伸一下,这是否意味着为单个模型拥有多个商店基本上没用?
当我们定义一个商店时,我们是在定义一个类(商店类型,如果我们可以这样称呼它的话),还是它是一个商店的实例?我问的原因是,当我们声明一个网格时,我们只是将存储配置传递给它store: 'MyApp.store.MyStore'
- 网格实例化该类型的网格,还是只是使用我们已经使用的存储实例化?
谢谢!
PS:+50 赏金给解释这一切的人 :) - 将在 48 小时结束后提供赏金..
【问题讨论】:
Extjs 中的代理违背了整个 KISS 原则。我会像躲避瘟疫一样避开它们。 【参考方案1】:The docs说:
模型代表您的应用程序管理的一些对象。
Store 只是模型实例的集合 - 通常从某处的服务器加载。
模型保存在商店中
不仅如此。模型可以单独使用(f.i. 用于用数据填充表单。查看Ext.form.Panel.loadRecord 了解更多信息)。
为什么模型上有代理配置和保存方法?我了解模型只能存储在商店中。
正如我所说,不仅如此。
为什么当我将模型对象添加到商店时,脏标志没有被清除?
为什么要这样做?只有当它与服务器端的相应记录同步时,Record 才会变得干净。
当我将模型对象添加到商店时,为什么模型没有获取该商店配置的代理?
这又是因为模型可以在没有存储的情况下使用。
代理是模型的静态配置。这是否意味着我们不能使用具有多个数据源的特定模型的对象?
我们不能使用特定模型的对象,但我们可以将一个模型定义用于多个商店。例如:
Ext.define('MyModel',
// ... config
);
var store1 = Ext.create('Ext.data.Store',
model: 'MyModel',
// ... config
proxy:
// ...
// this proxy will be used when store1.sync() and store1.load() are called
// ...
);
// ...
var storeN = Ext.create('Ext.data.Store',
model: 'MyModel',
// ... config
proxy:
// ...
// this proxy will be used when storeN.sync() and storeN.load() are called
// ...
);
由于 store1 和 storeN 使用不同的代理,这些存储所包含的记录可能完全不同。
当我们定义一个商店时,我们是在定义一个类(商店类型,如果我们可以这样称呼它的话),还是它是一个商店的实例?
是的,当我们定义一个 Store 时,我们就是在定义一个类。
我问的原因是,当我们声明一个网格时,我们只需将存储配置作为 store: 'MyApp.store.MyStore' 传递给它 - 网格是实例化该类型的网格,还是只是使用我们的存储?已经实例化了吗?
有几种方法可以为网格设置存储配置:
store: existingStore,
store: 'someStoresId',
store: 'MyApp.store.MyStore',
在第一种和第二种情况下,将使用现有的商店实例。在第三种情况下,将使用新创建的 'MyApp.store.MyStore'
实例。所以,store: 'MyApp.store.MyStore',
等于
var myStore = Ext.create('MyApp.store.MyStore', );
// ...
// the following - is in a grid's config:
store: myStore,
更新
当一个模型被添加到store,然后调用store的sync(),为什么模型的dirty flag没有被清除?
它应该被清除,除非没有正确设置读取器、写入器和服务器响应。查看writer example。 store 的 sync() 中自动清除了脏标志。
如果一个模型类根本没有被赋予任何代理,它为什么要跟踪它的脏状态?
让您知道记录自创建时起是否已更改。
通过引入模型将自身同步到服务器的概念来实现什么?
假设您正在创建一个包含一组简单输入的小部件。此输入的值可以从 db 加载(这组输入代表 db 表中的一行)。当用户更改输入值时,数据应发送到服务器。这些数据可以存储在一个记录中。
那么这个界面你会用什么:一条记录还是只有一条记录的商店?
独立模型 - 用于表示 db 表中的一行的小部件。Store - 用于表示 db 表中的一组行的小部件。
【讨论】:
1.将模型添加到store,然后调用store的sync()
,为什么没有清除model的dirty
标志?
2.如果一个模型类根本没有被赋予任何代理,为什么它会跟踪它的dirty
状态?
在我看来,模型是对象的客户端表示。模型应该只驻留在存储中,并且存储应该能够表示(通过使用内部代理)REST 存储、AJAX 位置或 InMemory 存储。引入模型将自己同步到服务器的概念可以实现什么?
另外需要注意的是,模型和商店可以各自有不同的代理【参考方案2】:
我从 ExtJS 2.2 [原文如此] 到 4,模型行为和术语也让我陷入了循环。
我能找到的最好的快速解释来自 Sencha 博客上“ExtJS 4 倒计时”系列中的 this post。结果表明模型之所以如此行事,是因为它“确实”是一个记录。
数据包的核心是 Ext.data.Model。一个模型 表示应用程序中的某种类型的数据 - 例如 电子商务应用程序可能具有用户、产品和订单的模型。在 最简单的模型只是一组字段及其数据。任何人 熟悉 Ext JS 3 的都会使用 Ext.data.Record,这是 Ext.data.Model 的前身。
这是令人困惑的部分:模型既是您正在使用的数据的模型和遵循该模型的对象的单个实例。 我们称它的两个用途为“Model qua model”和“Model qua Record”。
这就是为什么它的load
方法需要一个唯一的ID(句号)。模型 qua Record 使用该 ID 创建 RESTful URL,以检索(和保存等)单个 Record 价值数据。 RESTful URL 约定在 here 中进行了描述,并在 Sencha 的博客上链接到 this post,该博客专门讨论了模型的使用。
这里有一些 RESTful URLs 形成了该标准,让您熟悉格式,ExtJS 的模型似乎确实使用了这种格式:
对 id 为 1 的记录进行操作
GET /people/1 <<< That's what's used to retrieve a single record into Model
返回第一条记录id 为 2
DELETE /people/2
销毁第一条记录id 为 7
POST /people/7?_method=DELETE
等等等等
这也是为什么模型有自己的代理,以便他们可以通过修改为遵循conventions described in that link 的 URL 运行 RESTful 操作。您可能会从一个 URL 中提取 100 条记录,将其用作商店的代理源,但是当您想要保存单个模型中的内容时(再次,请在此处考虑“模型 qua 记录”) ,您可以通过另一个 URL 执行这些特定于记录的操作,该 URL 的后端一次与一条记录混淆。
那么我什么时候使用商店?
要存储该模型的多个实例,您需要将它们放入 Store。您将大量模型qua 记录添加到存储中,然后访问这些“模型”以提取数据。因此,如果您有一个网格,您自然希望在本地拥有所有数据,而不必为每一行的显示重新查询服务器。
来自first post:
模型通常与商店一起使用,商店基本上是 模型实例的集合。
当然,商店显然从 Model qua Model 那里提取信息,以了解他们携带的物品。
【讨论】:
【参考方案3】:我在 sencha App Architecture Part 2 的文档中找到了它
为模型使用代理:
这样做通常是一种很好的做法,因为它允许您加载和 无需存储即可保存此模型的实例。还有,当 多家商店使用相同的模型,您不必重新定义您的 代理每个人。
为商店使用代理:
在 Ext JS 4 中,多个商店可以使用相同的数据模型,即使 商店将从不同的来源加载他们的数据。在我们的示例中, SearchResults 和 Stations 将使用 Station 模型 store,两者都从不同的位置加载数据。一回 搜索结果,另一个返回用户喜欢的电台。到 实现这一点,我们的商店之一将需要覆盖代理 在模型上定义。
【讨论】:
以上是关于ExtJS - 如何使用代理,模型?它们有啥关系?的主要内容,如果未能解决你的问题,请参考以下文章
覆盖 ExtJS 模型 getter 和 setter 的最佳实践