使代理使用扩展的 Ext.data.Operation

Posted

技术标签:

【中文标题】使代理使用扩展的 Ext.data.Operation【英文标题】:Make proxy use extended Ext.data.Operation 【发布时间】:2012-05-17 14:30:10 【问题描述】:

我已扩展 Ext.data.Operation 以实现自定义 commitRecords 方法。

Ext.data.Operation 类用于商店与其代理之间的所有通信。

commitRecords 方法专门用于根据代理写入器返回的数据更新数据存储中的数据。

我似乎无法掌握如何设置代理以使用我的扩展版Ext.data.Operation

我一直在浏览Ext.data.* 包,但似乎找不到Ext.data.Operation 的创建位置,所以我会知道要告诉哪个类使用这个新的扩展Ext.data.Operation 类和自定义@987654329 @方法。

之前有没有人扩展过这个,能给我一些指点吗?

【问题讨论】:

【参考方案1】:

我找到了,Ext.data.Proxybatch 方法是创建Ext.data.Operation 对象以发送到服务器的地方。

我使用新的batch 方法扩展了Ext.data.proxy.Ajax,我只需为我自己的操作类切换new Ext.data.Operation

编辑

只是因为你问了 DmitryB。关于我为什么必须实现自己的 commitRecords 方法的简短故事是,我需要我的数据模型“internalId”字段来匹配实际的数据库记录 ID 字段。具体原因我就不说了,太复杂了,我无法表达,但这是我所做的:

我的理解是,commitRecords 方法在调用store.sync() 时作为最后一个操作之一被触发,只要您编写服务器端,它就会自动将客户端的脏记录替换为新的服务器端记录控制器在 Ajax 响应中返回新的服务器记录,它会在同步请求进行插入或更新时执行此操作。

commitRecords 的官方实现尝试通过使用数据模型的“internalId”字段将这条返回的服务器记录与脏客户端记录匹配。

显然,我不知道新记录的下一个增量数据库 ID 将是什么,因此我无法在记录与数据库同步之前在客户端将其分配为 ID,因此服务器记录永远不会匹配能够在调用 commitRecords 时匹配脏客户端记录的 internalId,即客户端记录不会获得我需要的正确数据库 ID。

所以,因为我的所有可写数据模型都有一个“create_time”字段,所以我决定让 commitRecords 方法使用“create_time”字段匹配服务器记录和客户端记录“internalId”。

这是扩展的 Ext.data.Operation 类,我在其中这样做:

Ext.define('MyApp.ux.QueryOperation', 
    extend: 'Ext.data.Operation',

    /** 
     * Use the date_created timestamp if we cant match to an ID.
     * This allows client records that did not previously exist on the server
     * to be updated with the correct server ID and data
     * NB: All implementing data models require a "date_created" field.
     */
    commitRecords: function (serverRecords) 
        var me = this,
            mc, index, clientRecords, serverRec, clientRec;
        if (!me.actionSkipSyncRe.test(me.action)) 
            clientRecords = me.records;
            if (clientRecords && clientRecords.length) 
                if (clientRecords.length > 1) 
                    mc = new Ext.util.MixedCollection();
                    mc.addAll(serverRecords);
                    Ext.each(clientRecords, function(clientRec) 
                        serverRec = mc.findBy(function(record) 
                            var clientId = clientRec.getId(),
                                clientTime = clientRec.get('date_created').getTime(),
                                serverTime = record.get('date_created').getTime();
                                if(clientId && record.getId() === clientId) 
                                    return true;
                                
                                // timestamp can be within 2ms of record
                                // (it seems to change slightly in serialization)
                                return (clientTime > serverTime - 2 && clientTime < serverTime + 2);
                        );
                        me.updateClientRecord(clientRec, serverRec);
                    );
                 else 
                    clientRec = clientRecords[0];
                    serverRec = serverRecords[0];
                    me.updateClientRecord(clientRec, serverRec);
                
                if (me.actionCommitRecordsRe.test(me.action)) 
                    for (index = clientRecords.length; index--; ) 
                        clientRecords[index].commit();
                    
                
            
        
    ,

);

正如我在答案中提到的,我发现我必须扩展代理才能使用我的新 Operation 类。我唯一扩展的是batch 方法,仅将方法中的两行替换为new Ext.data.Operation 现在说new MyApp.ux.QueryOperation(我上面的新操作类)。当响应从服务器返回时,这将调用我自己的 commitRecords 方法。我还给扩展代理一个别名“proxy.query”,这样我就可以告诉我的商店像这样使用它:

Ext.define('MyApp.store.MyStore', 
    extend: 'Ext.data.Store',
    requires: [
        'ST.ux.QueryProxy',
    ],
    title: 'Student',
    model: 'MyApp.model.MyModel',
    proxy: 
        type: 'query',
        // ... ^^^^^ uses my QueryProxy now
        // other configs...
    
);

(如果我似乎在使用这种错误的方式或遗漏了文档中的某些内容,请告诉我。我会更乐意使用实现此功能的内置方法。)

【讨论】:

很好的发现。不要害羞,分享一些代码:)谁知道呢,也许有一天它会很有用。 @DmitryB 好的,我自己解释了 我认为您的用例与许多人所面对的相似。根据我的经验,如果模型上的 ID 属性是“int”类型,则默认代理在运行 sync() 时会做正确的事情。我曾经将我的 ID 属性设置为一个字符串,这会导致同步失败,如您所述。本质上,我的网格记录将始终显示“脏”标志,即使它们已同步到服务器。

以上是关于使代理使用扩展的 Ext.data.Operation的主要内容,如果未能解决你的问题,请参考以下文章

wifi代理是啥意思

这一次搞懂Spring代理创建及AOP链式调用过程

代理扩展-隐式代理和多播代理

Chrome 扩展程序 - 以编程方式绕过代理

《设计模式之禅》--代理扩展:强制代理

基于 WebAssembly 的 Envoy 扩展 ——GetEnvoy 扩展工具包介绍