2013-07-21 22 views
4

我有了這個Backbone.Model代表谷歌圖書API量:Backbone.js的型號的默認值和解析

var Book = Backbone.Model.extend({ 

    defaults: { 
     volumeInfo : { 
      title: 'n.a.', 
      authors: 'n.a.', 
      publisher: 'n.a.', 
      publishedDate: 'n.a.', 
      imageLinks : { 
       smallThumbnail: '/unavailable.jpg' 
      } 
     } 
    }, 

    parse: function(resp) { 
     if (resp.volumeInfo.authors) { 
      resp.volumeInfo.authors = resp.volumeInfo.authors.join(','); 
     } 
     return resp; 
    } 
}); 

送到了這個模板:

<script type="text/template" id="bookCollectionRow"> 
    <tr> 
     <td><img class="thumbnail" src="<%= volumeInfo.imageLinks.smallThumbnail %>" /></td> 
     <td><a target="_blank" href="<%= volumeInfo.canonicalVolumeLink %>"><%= volumeInfo.title %></a></td> 
     <td><%= volumeInfo.authors %></td> 
     <td><%= volumeInfo.publisher %></td> 
     <td><%= volumeInfo.publishedDate %></td> 
    </tr> 
</script> 

在分析模板時,卷JSON不包含imageLinks我收到此錯誤:

Uncaught TypeError: Cannot read property 'smallThumbnail' of undefined. 

我知道我可以通過檢查Modeltemplate中的if來修復它,但defaults model屬性的目的是什麼?只有在不壓倒parse纔有效嗎?

回答

10

有幾件事。首先,一般不應該將嵌套對象作爲骨幹模型屬性 - 如果您始終可以以原子方式處理該屬性,則可以確定,但這是您不能時的完美示例。從數據模型的角度來看,imageLinks應該是它的骨幹模型類,就像volumeInfo一樣。其次,如果默認值是對象文字({})而不是函數,則使用相同的對象作爲每個模型實例的默認attrs。我想你想要這樣的:

defaults: function(){ 
    return { 
     volumeInfo : {} // should be new VolumeInfo({}) imo 
    }; 
}, 

但數據模型是更大的問題 - .defaults不會做那種嵌套對象模板的事情,你似乎是想對,並有很好的理由:它不能很好地工作,如果你沒有保持實例數據的穩定性,這隻會成爲你遇到的第一個陷阱。

+1

我不同意你在這裏的第一段。僅僅爲了一個子對象而使用另一個模型是矯枉過正的,並且使得從Google API逐字地獲取數據變得更加困難 – Bojangles

+0

我仍然試圖學習Backbone,但是從您所說的看來,它似乎並不是很好的解決方案來處理大部分的web服務:/至於'defaults'作爲對象字面量,我是按照這個教程:http://backbonetutorials.com/what-is-a-model/是那麼錯呢? –

+2

除了這不是一個子對象:它是具有狀態或行爲或相關的模型 - 它是一個*事物*,它負責縮略圖網址。試圖將外部API逐字映射到您的數據類型似乎也不是一個好主意。實際上,這就是爲什麼存在解析方法的原因:Google關於如何構建數據的選擇可能與您的數據相同或不同,如果不相同,則解析是在哪裏進行轉換。設置從外部數據中部分合並的模板對象樹是......邊緣情況容易說的最少。 – AdamKG