3

我有以下设置:

    App.module('TestUsers.Views', function(TestUsersViews, App, Backbone, Marionette, $, _) {
    TestUsersViews.UsersItemView = Marionette.ItemView.extend({
        template: testUsersItemViewTmpl
        , tagName: 'tr'
        , templateHelpers: {
            handleUndefined: function(val) {
                return (_.isUndefined(val) ? '' : val);
            }
        }
    });

    TestUsersViews.UsersTable = Marionette.CompositeView.extend({
        template: testUsersTmpl
        , tagName: 'table'
        , className: 'h-center'
        , itemView: TestUsersViews.UsersItemView
        , itemViewContainer: 'tbody'
        , initialize: function() {
            this.listenTo(this.collection, 'reset', function() {
                this.appendHtml = function(collectionView, itemView, index) {
                    collectionView.$el.append(itemView.el);
                }
            });
        }
    });
});

返回的 Collection 的结构是:

[ { "apiStandardProfileRequest": { "headers": { "_total": 1, "values": [ { "name": "x-li-auth-token", "value": "name:ksBx" } ] } , "url": " http://api.linkedin.com/v1/people/jGEI3X15sx " }, "firstName": "Eileen", "headline": "Kforce Professional Staffing 的交付总经理", "id" :“jGEI3X15sx”,“行业”:“人员配备和招聘”,“姓氏”:“亚当斯(LION)”,“位置”:{“国家”:{“代码”:“我们”},“名称”:“大波士顿地区”},“pictureUrl”:“ http://mclnkd.licdn.com/mpr/mprx/0_y_g-snorc6G3qFIa->bjSsz4yRb6un3EaOkWSszeCX3-yW5gmr5SOqvpuzEQPz6wGg8x2vtspSH8c", "siteStandardProfileRequest": { "url": " http://www.linkedin.com/profile/view ?>id=3633999&authType=name&authToken=ksBx&trk=api*a249733 }1*s25759}9 ..]

我呈现数据的模板是:

    <td id="<%= id %>"><img src="<%= pictureUrl %>" width="16"      height="16"/><%= firstName %> <%= lastName %></td>   
<td><%= headline %></td>
<td></td>
    <td><%= location.country.code %></td>
    <td><%= location.name %></td>
    <td><a href="<%= siteStandardProfileRequest.url %>">Full Profile</a></td>

但是,有些用户没有“pictureUrl”,我收到“未捕获的 ReferenceError:pictureUrl 未定义”错误。我不确定我做错了什么,未处理未定义的值。我相信这是一个简单的修复,任何帮助表示赞赏。

4

2 回答 2

3

简短答案 -覆盖 Marionette.ItemView 中的 serializeData

有两种选择。检查模板中未定义的类型或确保数据始终具有定义的模型属性。

第一个很麻烦,给模板增加了很多混乱。对于第二种情况,其他答案中提到的一种方法是使用模型默认值。但这又带来了另一个问题。

模型默认值旨在为始终具有有意义值的属性提供值。示例属性“isValid”可以具有默认值 true。但是“lastName”没有有意义的默认值。为这些值设置模型默认值具有将默认值保存到服务器的副作用,因为您唯一的要求是为视图/模板设置默认值。

为避免这种情况,您可以覆盖 Marionette.ItemView 中的 serializeData 以添加仅用于渲染的默认值。

Backbone.Marionette.ItemView.extend({
  serializeData: function(){
    return _.extend({}, 
      this.model.renderDefaults ? _.result(this.model, 'renderDefaults') : {}, 
      this.model.toJSON()
    );
  }
});

在模型中,您可以像这样设置默认值进行渲染

Backbone.Model.extend({
  renderDefaults : {
    pictureUrl : 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D'
  }
});

或者

Backbone.Model.extend({
  renderDefaults : function(){
    return {
      pictureUrl : 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D'
    }
  }
});
于 2013-10-08T13:46:40.470 回答
3

有很多方法可以处理这种事情,我将在下面概述一些一般策略。

在模板中

如果你想在模板中处理这个,那么你需要使用它typeof来检查是否pictureUrl存在,其他任何东西都会给你一个 ReferenceError原因我在别处描述的原因。

这种方法在您的模板中看起来像这样:

<% if(typeof pictureUrl !== 'undefined') { %>
    <img src="<%= pictureUrl %>" width="16" height="16">
<% } %>

您可能想说if(typeof pictureUrl !== 'undefined' && pictureUrl)您是否期望空pictureUrl值以及缺失值。

演示:http: //jsfiddle.net/ambiguous/7bXzf/

如果您想使用标准占位符头像,您还可以在该条件中添加一个else,这可能会使您的布局更漂亮和更一致。

在模型中

根据传入数据的精确格式,您可以使用您的模型defaults来提供占位符。在你的模型中这样的东西应该可以解决问题:

defaults: {
    //...
    pictureUrl: 'url-for-placeholder-avatar-goes-here',
}

pictureUrl: ''如果您不想要占位符,但您想<% if(pictureUrl) { %>在模板中包含一个检查以避免无效的 HTML,您也可以使用。

演示:http: //jsfiddle.net/ambiguous/BZAjJ/

如果您将模型写回服务器进行存储,您可能会遇到这种方法的问题。

于 2013-10-07T17:34:52.560 回答