11

テーブル ビューでレンダリングしたいモデルのコレクションがあります。各モデルはテーブル内の 1 つの行で表す必要があり、この行はテンプレートを使用して生成する必要があります。イベント ハンドラーをその行 (クリックなど) にアタッチできるはずです。イベントが発生すると、その行に関連付けられたモデルに関する特定の情報が警告されます。

これと同様のことを私が見た一般的な方法は、各行を独自のビューに分割し、親ビュー (この場合はテーブルとしましょう) で行ビューを使用して html を生成し、コードに含めることです。 . ただし、これがテンプレートでどのように機能するかわかりません。

この場合、RowView には dom 要素 (this.elバックボーン用) への参照がないため、イベントを特に RowView にアタッチすることはできません。単純に文字列を返します。テンプレートを最大容量まで使用しながら、どうすれば目的を達成できますか?

問題は、特にイベント、テンプレート化、またはネストされたビューの使用に関するものではなく、Backbone を使用してこの種の出力を実現する正しい方法に関するものです。

サンプルコード(フィドルでも):

/** View representing a table */
var TableView = Backbone.View.extend({
    tagName: 'table',
    render: function() {
        var rows = _.map(this.collection.models, function(p) {
            return new RowView({model: p}).render();                        
        });
        $('body').html(this.$el.html(rows.join('')));
    }
});

/** View representing a row of that table */
var RowView = Backbone.View.extend({
    render: function() {
        // imagine this is going through a template, but for now
        // lets just return straight html.
        return '<tr>' + 
                '<td>' + this.model.get('name') + '</td>' + 
                '<td>' + this.model.get('age') + '</td>' +
               '</tr>';
    }
});

var data = [
    {'name': 'Oli', 'age': 25},
    {'name': 'Sarah', 'age': 20}];

/** Collection of models to draw */
var peopleCollection = new Backbone.Collection(data);
var tableView = new TableView({collection: peopleCollection});
tableView.render();

ありがとうございました!

4

1 に答える 1

11

ビューの階層を処理する 1 つの方法は、各ビューにその子をレンダリングさせ、そのel. その後、モデル/コレクションに従って、各ビューによってイベントが処理されます。

HTML をビューとして挿入elしてコンテナ要素を制御するには、setElementメソッドを使用できます。

setElement view.setElement(element)

バックボーン ビューを別の DOM 要素に適用する場合は、setElement を使用します。これにより、キャッシュされた $el 参照も作成され、ビューの委任イベントが古い要素から新しい要素に移動されます。

あなたの例は次のように書き直すことができます

var rowTemplate=_.template("<tr>"+
     "<td class='name'><%= name %></td>"+
     "<td class='age'><%= age %></td>"+
     "</tr>");

/** View representing a table */
var TableView = Backbone.View.extend({
    tagName: 'table',

    initialize : function() {
        _.bindAll(this,'render','renderOne');
    },
    render: function() {
        this.collection.each(this.renderOne);
        return this;
    },
    renderOne : function(model) {
        var row=new RowView({model:model});
        this.$el.append(row.render().$el);
        return this;
    }
});

/** View representing a row of that table */
var RowView = Backbone.View.extend({  
    events: {
        "click .age": function() {console.log(this.model.get("name"));}
    },

    render: function() {
        var html=rowTemplate(this.model.toJSON());
        this.setElement( $(html) );
        return this;
    }
});

var data = [
    {'name': 'Oli', 'age': 25},
    {'name': 'Sarah', 'age': 20}];

/** Collection of models to draw */
var peopleCollection = new Backbone.Collection(data);
var tableView = new TableView({collection: peopleCollection});
$("body").append( tableView.render().$el );

そしてフィドルhttp://jsfiddle.net/9avm6/5/

于 2012-04-26T08:10:14.860 に答える