3

モデルのフィールドで前処理を行う良い方法は何ですか。たとえば、次のデータがあるとします。

[{
        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
}

そのため、すべてのモデルでその前処理を実行したくありません。私は私の考えでそれをするべきですか?もしそうなら、どのように?いくつかの解決策を読みましたが、この状況には当てはまらないものもあれば、ハックのように見えるものもあります。

ありがとう!

アップデート

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}}
4

5 に答える 5

2

この種のプレゼンテーション ロジックは、ライブラリ スタックがサポートしている場合、テンプレート ヘルパーに配置する必要があります。getShortenedMessage(length)そうでない場合は、モデルにメソッドを追加し、それを使用して値を取得してください。いずれにせよ、実際のモデルの属性を単に変更して表示しないでください。これは悪い設計であり、後であらゆる種類の複雑さを引き起こす可能性があります。

于 2012-11-30T19:51:58.343 に答える
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')
});

私はいくつかの機能を持つビュー ヘルパーを取得する傾向があります。モデルからプレゼンテーション ロジックを除外するのに役立ちます。計算された値をテンプレートに渡すことで、テンプレートがより読みやすく、管理しやすくなります。

また、テキストの切り捨てなどは、非常に一般的なタイプの機能であるため、非モデル固有のヘルパーに配置できます。

于 2012-11-30T22:12:34.807 に答える
1

ライブラリを使用できますunderscore.string(リンク)

基本的に、render 関数で関数 truncate/prune ( Link ) を呼び出すだけで、短縮版が返されます。

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

メッセージの長さが文字数を超えていない場合は、単に文字列を返します。と併用することもできますのでご注意くださいUnderscore.js

于 2012-12-01T19:34:22.697 に答える
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>

ボーナス ポイントについては、カスタム ゲッターを使用します (IE9+ でサポートされています)。したがって、プロパティのように見えますが、呼び出されたときにのみ関数を処理します。セッターがないので設定できません。

于 2013-10-22T05:15:21.810 に答える
0

モデル コンストラクターを作成し、コンストラクター内に設定する前に文字列が長すぎる場合は短くします。コンストラクターの詳細については、このページを参照してください。Model

于 2012-11-30T19:54:27.737 に答える