2013-08-06 74 views
2

我試圖通過避免任何請求我可以儘量減少服務器調用。管理模型實例的好主幹模式是什麼?

比方說,爲了舉例說明,我有一組屬於用戶且分配了標籤的Matchboxes集合,然後還有一組標籤和一組用戶作爲其他頁面的一部分。獲取匹配框可以檢索用戶和標籤信息,以便我可以用一個請求實例化所有需要的模型,訪問標籤和用戶頁面可以檢索類似的集合(只有它們只處理它們各自的模型)。

我的問題:如果火柴盒是一個頁面,標籤和用戶是兩個其他頁面,確保只有一個模型被實例化爲任何給定實體的好方法是什麼。如果我進入用戶或標籤並編輯與火柴盒相關聯的條目,則火柴盒條目應該分配有相同的條目,以允許其監聽並響應更新,而在返回示例中的火柴盒頁面時不需要發送請求。

我已經看過Backbone.relational,但它似乎並沒有做我所需要的,並且不願將自己置於框架之中。因此涉及模式的解決方案更可取

回答

1

結束了使用http://pathable.github.io/supermodel/它使用與調用一個特殊Model.create本身返回的現有的(如果有必要更新用新值),例如自定義的功能覆蓋在集合上model屬性的模式說模型。 Model.create調用必須在代碼中的其他地方用於獨特的模型。

因此,基本上每個模型都有一個all()方法,它是通過id的所有實例的集合。無論何時添加模型,都會根據集合進行檢查,並返回現有對象(如果存在);用於實例化副本的數據用於更新現有對象,以確保數據不失效(這對我所希望的唯一性來說是一個不錯的獎勵)。

最簡潔的方法似乎是將模型函數包裝到一個函數中,該函數將其返回以供更清晰地使用;那麼對於每個需要具有獨特模型的集合在功能中包裝所述模型。我想出了這個此刻:

app.single = function (modelPrototype) { 
    return function (attrs, options) { 
     return modelPrototype.create(attrs, options); 
    }; 
}; 

app存在僅僅是一個全球性的,依賴於特定的命名空間)

所以在收藏,而不是,

model: app.Model 

我會然後使用

model: app.single(app.Model), 

每當我更新一個應用程序的一部分條目時,更改將逐漸下移到每個其他集合/模型,因爲如果從用戶的角度來看它是相同的實例,則它也是代碼中的同一實例。

這就是我通過閱讀代碼和文檔所瞭解的模式。這對我自己的用途來說已經足夠了。

我懷疑這個解決方案仍然會有一些問題,如果你緩存渲染,但我還沒有找到一個用途(寧願重新渲染,只要我可以避免處理各種工件),所以這一切都很好爲了我。

不幸的是,代碼庫似乎被部分拋棄,所以雖然它與Backbone 1.0.0一起工作(就獨特的模型而言),但我可能需要在未來的項目中重新創建/分離模式。

0

我覺得你應該三思而後行,以這種方式嵌套你的模型和集合,特別是如果它主要是爲了簡化你的應用程序的引導。相反,儘可能使用id在模型之間進行相互引用。如果您現在以某種方式構建您的模型/集合樹,那麼您所擁有的這個設計問題很可能只是許多問題中的第一個,而後來才發現它太不靈活。這就是說,如果所有你需要的是模型引用其他模型/集合能夠引用相同的模型/集合實例,那麼簡單地在引導期間實例化它們並將它們傳遞到它們各自的父模型將是足夠。您既可以裝載一些引導數據在一個請求,或最好內嵌在HTML中的數據:

<script> 
var bs_data = { 
    users : [ 
     ... 
    ], 
    tags : [ 
     ... 
    ], 
    matchboxes : [ 
     ... 
    ] 
}; 
</script> 

然後實例使用bootstap數據對應的模型或集合。

var matchboxes = new Matchboxes(); 
matchboxes.set(bs_data.matchboxes); 

var users = new Users({matchboxes:matchboxes}); 
users.set(bs_data.users); 

引導數據將來自相同的後端,因此您的模型和集合已經可以同步而無需獲取任何內容。

至於設計模式;作爲構造函數參數傳遞依賴關係實際上是依賴注入模式,儘管存在更多的自動化解決方案。

+0

我真的不想有這樣的代碼:'new Users({matchboxes:matchboxes})',因爲這意味着每次我想共享數據時,我只需要添加交叉引用。 – srcspider

+0

我同意,因此第一段。除非使用集合時常見的特定集合模型關係,否則不應嵌套模型和集合。但是你仍然需要一些將它們相互關聯的方式。這就是爲什麼我建議在需要時存儲相關模型的ID。 – nordhagen

0

爲了確保只有一個模型被實例化,並且在使用它的其他元素之間共享,可以在任何元素對其進行更改時偵聽和更新,您可以使用Singleton模式。你可以閱讀更多關於它的信息here

如果你使用Requirejs,你可以得到相同的效果,如果你總是返回實例化的模型。例如:

// the shared model 
define([ 
    'jquery', 
    'underscore', 
    'backbone' 
], function ($, _, Backbone) { 
    'use strict'; 

    var Model = Backbone.Model.extend({ 

    // ... 

    }); 
    // return instantiated, so we'll get the same object back whenever we use this model (singleton) 
    return new Model(); 

}); 

// a view using the model 
define([ 
    'jquery', 
    'underscore', 
    'backbone', 
    'model' 
], function ($, _, Backbone, modelInstance) { 
    'use strict'; 

    var View = Backbone.View.extend({ 
    initialize: function() { 
     // listen to what other elements do 
     this.listenTo(modelInstance, 'eventFromOtherElement', this.doSomething); 
     // when this element does something, other elements should be listening to that event 
     modelInstance.trigger('thisViewEvent'); 
    }, 
    doSomething: function() { 
     // ... 
    } 
    }); 
    return View; 
}); 
+0

我不是真的想要一個模型,我想要的是每個獨特模型的單個實例。 – srcspider

+0

不知道我是否理解你的意思:使用單例方法,您可以在模型中共享一個模型實例... –

+0

這就是問題所在。我想要獨特的實例,而不是一個單一的實例。也許我誤解了你的代碼中的評論。我沒有使用AMD,因爲我沒有在我的私人代碼中看到任何優勢,所以也許我錯過了與AMD的工作方式有關的東西?我的理解是,你的代碼生成一個單一的對象... – srcspider

相關問題