2012-05-09 55 views
5

我擴展了Ext.data.Operation來實現自定義commitRecords方法。Make proxy use extended Ext.data.Operation

Ext.data.Operation類用於商店及其代理之間的所有通信。

commitRecords方法專門用於根據從代理編寫器返回的數據更新數據存儲中的數據。

我似乎無法掌握如何設置代理以使用我的擴展版本Ext.data.Operation

我已經膛線通過Ext.data.*包,但似乎無法找到在Ext.data.Operation創建,所以我知道該怎麼告訴類中使用這個新的擴展Ext.data.Operation類定製commitRecords方法。

有沒有其他人在此之前擴展過,可否給我一些指點?

回答

4

我發現它,batch方法Ext.data.Proxy是創建一個Ext.data.Operation對象發送到服務器。

我將Ext.data.proxy.Ajax擴展爲新的batch方法,我只是將new Ext.data.Operation換爲我自己的操作類。

編輯

只是因爲你問DmitryB。關於爲什麼我必須實現自己的commitRecords方法的小故事是,我需要我的數據模型「internalId」字段來匹配實際的數據庫記錄ID字段。我不會進入到底爲什麼,這太令人費解了我表達,但這裏是我所做的:

怎麼我的理解,呼籲store.sync()commitRecords方法燒製的最後行動之一,它會自動替換隻要您編寫服務器端控制器以在Ajax響應中返回新的服務器記錄,客戶端上的新記錄就會記錄在新的服務器端記錄中,只要同步請求執行插入或更新操作就會執行此操作。

commitRecords的官方實現嘗試使用數據模型的「internalId」字段將此返回的服務器記錄與髒客戶端記錄進行匹配。

顯然,我不知道下一個增量數據庫ID將用於新記錄,所以我不能在客戶端將其作爲ID在數據庫與記錄同步之前分配,因此服務器記錄將永遠不會當調用commitRecords時,匹配能夠匹配髒客戶端記錄的internalId,即客戶端記錄不會獲得我需要的正確數據庫ID。

如此,因爲爲這個應用程序我寫的數據模型的所有有一個「CREATE_TIME」字段我決定把commitRecords方法使用,而不是「internalId」中的「CREATE_TIME」領域的客戶記錄匹配服務器記錄。

這裏是擴展的Ext.data。操作類,在那裏我做:

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(); 
        } 
       } 
      } 
     } 
    }, 

}); 

正如我在答覆中提到,我發現我不得不延長代理要利用我的新工作類。我擴展的唯一方法是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... 
    } 
}); 

(如果它看起來像我要對這個錯誤的方式還是錯過了一些在docs,請讓我知道,我會更樂意用內置的方法來實現此功能。)

+0

很好找。不要害羞,並分享一些代碼:)誰知道,也許有一天它會很有用。 – dbrin

+0

@DmitryB好的,我解釋了我自己 – Geronimo

+0

我認爲你的用例與許多人面對的相似。根據我的經驗,如果您的模型上的ID屬性是'int'類型,那麼默認代理在運行sync()時會執行正確的操作。我曾經有我的ID屬性字符串,並導致同步失敗提交操作,如你所描述的。實質上,我的網格記錄將始終顯示「髒」標誌,即使它們已同步到服務器。 – dbrin