骨干中的预处理模型

时间:2012-11-30 19:44:44

标签: javascript backbone.js preprocessor

对模型的字段进行一些预处理有什么好方法。例如,假设我有这些数据:

[{
        id: '1',
        sender: 'me',
        receiver: 'you',
        message: "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum",
        date: new Date("October 13, 1975 11:13:00").toLocaleDateString()
    }]

在这个简单的模型中:

App.Models.Notification = Backbone.Model.extend({
    defaults: {
        'date': new Date()
    }
});

我希望减少message值中的字符数,以便在视图中显示它,但前提是该消息包含的字符数超过给定数量。也许是这样的:

if ( this.model.get('message').trim().split(" ").length > 30 ) {
  // code here
}

所以,我不想在所有模型中执行预处理。我应该在我看来这样做吗?如果是这样,怎么样?我有read一些解决方案,但其中一些不适用于这种情况,而其他一些似乎是黑客攻击。

谢谢!

更新

根据Alex的建议并作为参考,我在这里举了一个使用Handlebars模板助手的例子:

render: function() {

    Handlebars.registerHelper('getShort', function(options) {
        if ( options.fn(this).trim().split(" ").length > 30 ) {
            var message = options.fn(this);
            var shortText = $('<div/>', { text: message })
            .html()
            .trim()
            .substring(0, 200)
            .split(" ")
            .slice(0, -1)
            .join(" ") + "..."

            return shortText;
        }
        return options.fn(this);
    });

    template = Handlebars.compile( $("#my-template").html() );
    this.$el.html( template( this.model.toJSON() ));
    return this;
}

并像这样使用它:

的index.html

{{#getShort}}{{message}}{{/getShort}}

5 个答案:

答案 0 :(得分:2)

如果您的库堆栈支持,那么这种表示逻辑应该放在模板助手中。如果没有,只需将getShortenedMessage(length)方法添加到模型中并使用它来获取您的值。在任何情况下,不要改变实际的模型属性只是为了以不同的方式显示它 - 这是糟糕的设计,可能会导致各种各样的复杂化。

答案 1 :(得分:1)

最佳做法是将这种逻辑放入外部辅助函数中,然后将结果传递给模板。

例如,如果您有这样的事情:

var NotificationHelper = {
    trimmedMessage: function (notification, limit) {
        // do trimming logic here based on notification.get('message')
        return value;
    }
    ... // other helper functions
};

给出这样的模板:

template: _.template('<p><%- message %></p><p><%= foo %></p>'),

然后在您的视图代码中,您可以执行以下操作:

this.$el.html( this.template({
    message: NotificationHelper.trimmedMessage(this.model),
    foo: this.model.get('foo')
});

我倾向于获得具有多个功能的视图助手。它有助于使表示逻辑远离模型。通过将计算值传递到模板中,它将使您的模板更具可读性和可管理性。

此外,截断文本等内容可以放在非特定于模型的帮助器中,因为它是非常通用的功能类型。

答案 2 :(得分:1)

您可以使用underscore.string库(Link

基本上,您只需在render函数中调用函数truncate / prune(Link),这将返回缩短的版本..

render: function() {
     var shortenedMessage = _('Hello, world').prune(8); // => 'Hello...'
}

如果消息长度不高于字符数,则只返回字符串。 请注意,您也可以将其与Underscore.js一起使用。

答案 3 :(得分:1)

通常最好在模型中使用一个函数。这样,任何使用该模型的人都可以重复使用它。模板可以调用该函数,它只会在您需要时进行处理。

App.Models.Notification = Backbone.Model.extend({
    defaults: {
        get shortdate() {
            // put the code here to return the custom date format
        }
    }
});

// in the template (or anywhere else)
<div id='date'><%= Notification.shortdate %></div>

对于奖励积分,请使用自定义getter(在IE9 +中支持)。所以它看起来像一个属性,但只在它被调用时处理该函数。由于没有设定器,因此无法设置。

答案 4 :(得分:0)

创建一个模型构造函数,如果在构造函数中设置它之前它太长,则缩短字符串。有关Model构造函数的详细信息,请参阅此page