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 的最佳实践

如何在extjs中使用内存代理执行checkboxmodel的selectAll操作

实体关系模型和关系模型有啥区别?

extjs 5 商店同步绑定到选择 hasMany

在 ExtJS 中使用代理

DOM 级别有啥区别,它们是如何相互关联的?