4

我有这个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.

我知道我可以通过检查ifinModel或 in来修复它,但是模型属性template的目的是什么?defaults只有在不覆盖的情况下才有效parse吗?

4

1 回答 1

10

一些东西。首先,一般情况下,您不应该将嵌套对象作为主干模型属性——如果您始终可以原子地处理该属性,则可以,但这是一个很好的例子,说明您何时不能。从数据模型的角度来看,imageLinks 应该是它自己的主干模型类,volumeInfo 也应该如此。

其次,如果 defaults 是对象字面量 ( {}) 而不是函数,则相同的对象将用作每个模型实例的默认属性。我想你想要这个:

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

但是数据模型是更大的问题 - .defaults 并没有做你似乎想要的那种嵌套对象模板,并且有充分的理由:它不能很好地工作,这只是第一个如果你不保持你的实例数据相当平坦,你会遇到很多问题。

于 2013-07-21T19:14:42.517 回答