Backbone.js模型的默认设置和解析 [英] Backbone.js Model defaults and parse
问题描述
我有这个Backbone.Model
代表Google Books API卷:
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.
我知道我可以通过在Model
或template
中使用if
检查来修复它,但是defaults
模型属性的目的是什么?仅在不覆盖parse
的情况下才有效吗?
一些事情.首先,一般来说,您不应将嵌套对象作为主干模型属性-如果您始终可以原子地对待该属性,则可以,但是这是您不能做到这一点的完美示例.从数据模型的角度来看,imageLinks应该是它的 own 骨干模型类,而volumeInfo也应该是它.
第二,如果默认值是对象文字({}
)而不是函数,则将同一对象用作每个模型实例的默认属性.我想你想要这个:
defaults: function(){
return {
volumeInfo : {} // should be new VolumeInfo({}) imo
};
},
但是数据模型是一个更大的问题-.defaults不会执行您似乎想要的那种嵌套对象模板的事情,并且有充分的理由:它不能很好地工作,这只会如果不保持实例数据的平稳性,就会遇到很多陷阱中的第一个.
I've got this Backbone.Model
representing a Google Books API volume:
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;
}
});
Which is fed to this template:
<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>
Upon parsing the template, when a volume JSON does not contain an imageLinks
I receive this error:
Uncaught TypeError: Cannot read property 'smallThumbnail' of undefined.
I know I could fix it by checking with an if
in the Model
or in the template
but what's the purpose of defaults
model property then? Does that work only if not overriding parse
?
A few things. First, you shouldn't have nested objects as backbone model attributes in general - it can be OK if you can always treat the attribute atomically, but this is a perfect example of when you can't. From a data-model perspective, imageLinks should be its own backbone model class, as should volumeInfo.
Second, if defaults is an object literal ({}
) instead of a function, the same object is used as the default attrs for each model instance. I think you want this:
defaults: function(){
return {
volumeInfo : {} // should be new VolumeInfo({}) imo
};
},
But the data model is the bigger issue - .defaults doesn't do the kind of nested-object-template thing you seem to be going for, and for good reason: it doesn't work well, this will just be the first of many gotchas you'll run into if you don't keep your instance data pretty flat.
这篇关于Backbone.js模型的默认设置和解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!