2011-11-28 73 views
14

我在ExtJS 4中遇到了MVC模式的問題。至少我認爲我有。在與這個問題接觸過多個人,並在Sencha論壇上發表過無數次後,我現在正在轉向更廣泛的觀衆,希望得到一個燈泡或確認。ExtJS 4 MVC視圖和子/子控制器難題的多個實例

問題

您的應用程序打開很多不同的意見,其中一些本身是小型應用程序的能力。此外,用戶可能希望打開一個視圖的多個併發副本。

此應用程序是一個單頁面的客戶端JavaScript應用程序。

ExtJS 4 MVC模型期望您定義應用程序類中的所有控制器。這些控制器隨後在應用程序加載時初始化。控制器跟蹤視圖,模型和商店。

當您多次初始化控制器,說創建視圖的多個副本,你最終指向同一數據存儲和功能上發送重複事件應用程序事件總線兩種觀點。

我通過向組件和控制器添加新的原型方法來重構我的應用程序,以允許a)子控制器(我的一些控制器變得非常大)以及b)專門爲它們的視圖定義存儲。模型仍然可以在控制器上定義,只是爲了方便處理程序使用,如果您需要執行類似於從服務器獲取記錄的操作。

問題

我的MVC的理解將導致我相信模型更直接關係到視圖不是那麼控制器。 我鼓勵ExtJS 4決定將控制器的商店(我認爲可以看作是更經典的模型的包裝)附加到控制器上,以鼓勵重新使用已加載的數據,並優化遠離同一類的許多副本實例化。然而,在我看來,如果一個人打算讓許多用戶可以看到的視圖實例,就不能這樣做。在我看來,擁有很多實例是面向對象框架中的一個重要選項,因此我反對這一趨勢並在某些基礎類實現了原型。 (謝謝Ext.implement!)。

有什麼辦法有使用開箱裝入他們與不同的數據視圖的多個併發實例所提供的制定者,吸氣等MVC類和製作用途?

+1

那麼究竟是什麼問題呢?我在** Question **部分沒有看到明確而連貫的問題。請更新你的問題,以包括一個問題,可以用事實,參考資料(不主觀,有意見等)回答。 – casperOne

+0

一致性增加 – aenigmatic

+0

太棒了,謝謝! – casperOne

回答

0

當然。是什麼讓你相信呢? 這裏是創建一個從Window組件擴展的自定義View的例子。您可以從同一個控制器多次運行此方法,並且每次您將獲得View的新實例。

「這」指的是代碼運行在一個控制器:

 this.getRequestModel().load(requestID,{  //load from server (async) 
       success: function(record, operation) { 
         var view = Ext.widget('requestEdit',{ 
          title: 'MyRequest '+requestID 
         }); 
         var form = view.down('form'); 
         form.loadRecord(record); 
       } 
     }); 
+0

這很好,但它在MVC包中並不真正運行。這也將單個記錄加載到視圖中。我指的是用附加的商店創建多個視圖實例。 – aenigmatic

+0

我不明白你在這裏問什麼。你可以多次使用Ext.create('MyView')嗎?是。有什麼問題? – dbrin

0

如何創建您的看法?我看不出爲什麼你無法將不同的商店或配置數據傳遞給每個對象。一些代碼示例可以幫助你正在做什麼。例如,我們有一個類似的探測應用程序,一切都通過擴展完成。所以,如果我們需要一個網格,我們運行

Ext.define('MyApp.grids.something',{ 
extends:'Ext.grid.panel' 
//... 

這些類是預定義的。然後,當控制器或視圖加載此格,他們正在使用

var grid=Ext.create('MyApp.grids.something',{id:'unique',store:mystore}); 

正如你所看到的,我們可以通過不同的配置選項每次創建時傳遞給同一電網。我們可以準確地把它當作你對待

Ext.create('Ext.grid.Panel'); 

當然除了我們做一些預定義的選項,以及一些非覆蓋,能,等等。

希望這有助於。

8

我面臨着類似的問題:

考慮該打開的每個客戶視圖的新實例一個CRM型應用程序中的一個tabpanel。並且說標籤視圖包含3或4個行編輯網格面板,用於與與該客戶端相關的不同數據集合進行交互。

我想出的解決方案基於來自Sencha論壇的this。在堅果外殼中,幾乎所有從視圖派發的事件都包含對視圖本身的引用。我的控制器控制功能中的處理程序都使用這些來獲取對正確視圖實例的引用。

對於處理需要此相同商店的多個實例,我把這個給心臟從該職位:

有關視圖或一個全球性的存儲實例...依賴於需要 。如果你打算使用全球化,那麼把它變成全球化的。如果你只在視圖上需要它,然後把它放在視圖上。 MVC是 不是法律,你可以改變它以適應你的需求。從技術上講,MVC的控制器部分假設是 視圖和模型部件之間的中間人,但有時候這只是不需要的。我在95%的時間內創建了 Store。我給你舉一個例子...

如果你有一個商店的產品,你可能只需要參考 存儲在您的網格。這通常不需要 其他部分的應用程序。但是,如果您有商店來加載國家/地區,我通常在全球範圍內需要它,因此我只需加載一次,然後 就可以在多個視圖中設置/使用該商店。

因此,我只是在視圖的initComponent方法內創建了與視圖實例相關的所需商店。該應用程序確實有一些全球商店,我遵循MVC建議作爲商店類創建。它很好地封裝視圖中的視圖實例存儲。然後我只需要一個控制器實例。

要專門回答您的問題,目前沒有ExtJS官方建議或配置來處理使用相同商店構造函數的相同視圖的多個實例。我花了一些時間尋找這樣的事情,而我發現的最好的是來自其論壇版主之一的這一建議。

+0

OP *真的*需要接受這個答案! – HDave

2

這可以很容易地完成。您需要遵循以下幾條規則:

  1. 在應用程序啓動時加載您的控制器。不要卸載它們。不要擔心內存或時間,即使對於數百個控制器,只要您最小化和連接您的js,它就非常小。

  2. 切勿使用控制器的參考或視圖屬性。您將使用控制器的一個實例,但使用多個視圖實例,因此您不需要引用視圖。

  3. 只在控制器中使用事件偵聽器。你只會聽你的意見事件。您可以通過處理程序中的「cmp」參數始終獲取對事件處理程序中視圖的(臨時)引用。

  4. 要「啓動」一個視圖,創建它並將其添加到另一個視圖。摧毀它,摧毀它。您不使用控制器來啓動視圖。您可以使用afterrender和beforedestroy控制器中的事件來添加邏輯。

+0

到目前爲止,這麼好。但是,創建的視圖上商店的獨特副本如何? – HDave

1

在ExtJS'MVC控制器是一個單一的你查看。我喜歡DeftJS如何看待MVC。視圖的每個實例都有一個自己的控制器實例。通過這種方式,您可以將所有「控制規則」放入視圖的特定部分的控制器中,並且僅在視圖打開時纔會實例化。

我沒有任何經驗,我可以在同一個項目中使用多個Defts JS應用程序。

0

結賬this post。這個想法有采取從視圖中配置一些配置(如storeitemId),並把它放入視配置:

// .../app/view/Viewport.js 
Ext.define('MyApp.view.Viewport', { 
    // ... 
    items: [ 
     // ... 
     { xtype: 'testview', store: 'Store1', itemId: 'instance1' }, 
     { xtype: 'testview', store: 'Store2', itemId: 'instance2' } 
    ] 
}); 

與商店的問題將得到解決,效果顯着。不同的itemId s將使您能夠正確處理事件。