假設我正在處理一個返回JSON數據但具有複雜或可變結構的API。例如,一個字符串值屬性可能是一個普通的文字,或者可以用語言來標記:面向對象的模型和backbone.js
/* first pattern */
{ "id": 1,
"label": "a foo"
}
/* second pattern */
{ "id": 2,
"label": [ {"value": "a foo", "lang": "en"},
{"value": "un foo", "lang": "fr"}]
}
在我的客戶端代碼,我不希望有視圖代碼擔心是否一個標籤有多種語言可供選擇,或者選擇哪一個等等。或者我可能想隱藏詳細的JSON結構,原因是其他原因。所以,我可能會在一個對象用合適的API包裝的JSON值:
/** Value object for foo instances sent from server */
var Foo = function(json) {
this.json = json;
};
/** Return a suitable label for this foo object */
Foo.prototype.label = function() {
var i18n = ... ;
if (i18n.prefLang && _.isArray(this.json.label)) // ... etc etc
};
所以這一切都非常正常value-object pattern,這是有幫助的,因爲它更從具體JSON結構,更容易測試等脫鉤好,好。
我目前看不到解決方法是如何使用Backbone和Marionette中的這些值對象之一。具體來說,我想使用Foo
對象作爲Backbone Model
的基礎,並將其綁定到Marionette ItemView
。然而,據我所看到的,在Model
值是直接取自JSON結構 - 我看不到的方式來識別的對象是函數:
var modelFoo = new Backbone.Model(foo);
> undefined
modelFoo.get("label").constructor
> function Function() { [native code] }
所以我的問題是:什麼將Backbone Model
的屬性與給定的JSON結構的特性(如複雜的API值)分離是一種好方法?可以評估對象,模型和視圖的好壞嗎?
編輯
讓我補充一個例子,因爲我認爲上述重點放在國際化問題的例子只是傳達我所關注的一部分。簡化一下,在我的領域,我擁有包括河流,湖泊和潮間帶的水體。水體與一個或多個採樣點相關聯,並且每個採樣點具有最新的樣本。這可能來自於數據API回服務器上,就像這樣:
{"id": "GB12345678",
"centre": {"lat": 1.2345, "long": "-2.3456"},
"type": "river",
"samplingPoints": [{"id": "sp98765",
"latestSample": {"date": "20130807",
"classification": "normal"}
}]
}
所以,在我看來代碼,我能寫表達式,如:
<%= waterbody.samplingPoints[0].latestSample.classification %>
或
<% if (waterbody.type === "river") { %>
但這樣會很糟糕,並且如果API格式發生變化就很容易被破壞。稍微好一些,我可以將這些操作抽象爲模板幫助函數,但仍然很難編寫測試。我想要做的是有一個值對象類Waterbody
,讓我查看代碼可以是這樣的:
<%= waterbody.latestClassification() %>
一個我與木偶發現的主要問題是堅持上調用toJSON()
模型傳遞給視圖,但也許一些計算出來的屬性建議有辦法解決這個問題。
你可能想看看模型中'serializeData'的用法。您可以以任何您認爲適合該視圖的方式來操縱模型。 – kalley
更新了我的回答,以便對您的編輯進行回覆 – Creynders