11

Backbone.jsを使用してコレクションをビューに関連付けたページ( RowsView、creates )を使用して、コレクション内の各モデル<ul>のサブビュー( 、creates)を作成すると、これらのモデルのインライン編集を設定する際に問題が発生します。コレクション。RowView<li>

ビューにコンテンツをテキストボックスに置き換えるedit()メソッドを作成しました。ユーザーがそのテキストボックスでを押した場合、リスト内の次のビューのメソッドをトリガーしたいと思います。RowViewlitabedit()

コレクション内の次のモデルのモデルを取得できます。

// within a RowView 'keydown' event handler
var myIndex = this.model.collection.indexOf(this.model);
var nextModel = this.model.collection.at(myIndex+1);

しかし、問題は、そのモデルに関連付けられているビューを見つける方法です。親RowsViewビューは、すべての子ビューへの参照を保持しません。そのrender()方法は次のとおりです。

this.$el.html(''); // Clear
this.model.each(function (model) {
    this.$el.append(new RowView({ model:model} ).render().el);
}, this);

その下にあるすべてのポインタへのポインタの個別の配列を保持するために、それを書き直す必要がありRowViewますか?または、既知のモデルがアタッチされているビューを見つけるための賢い方法はありますか?

問題全体のjsFiddleは次のとおりです。http://jsfiddle.net/midnightlightning/G4NeJ/

4

2 に答える 2

14

ビューへの参照をモデルに保存するのはエレガントではありませんが、ビューをイベント付きのモデルにリンクするには、次のようにします。

// within a RowView 'keydown' event handler
var myIndex = this.model.collection.indexOf(this.model);
var nextModel = this.model.collection.at(myIndex+1);
nextModel.trigger('prepareEdit');

RowViewでイベントprepareEditをリッスンし、そのリスナーでedit()を呼び出します。次のようになります。

this.model.on('prepareEdit', this.edit);
于 2012-07-13T15:55:58.463 に答える
2

RowsViewそのコンポーネントを追跡する必要があると思いますRowView。個々RowViewのは実際にはの一部でありRowsView、ビューがその部分を追跡する必要があることは理にかなっています。

したがって、次のようなメソッドRowsViewがあります。render

render: function() {
    this.child_views = this.collection.map(function(m) {
        var v = new RowView({ model: m });
        this.$el.append(v.render().el);
        return v;
    }, this);
    return this;
}

Tab次に、をのインデックスに変換する方法が必要ですthis.child_views


1つの方法は、イベントを使用することです。バックボーンビューがBackbone.Events混在しているため、ビューはそれ自体でイベントをトリガーでき、他のものはそれらのイベントをリッスンできます。あなたの中RowViewにこれを持っている可能性があります:

events: {
    'keydown input': 'tab_next'
},
tab_next: function(e) {
    if(e.keyCode != 9)
        return true;
    this.trigger('tab-next', this);
    return false;
}

そして、あなたの意志とあなたはRowsViewこのような種類を持つことができます:v.on('tab-next', this.edit_next);this.collection.mapedit_next

edit_next: function(v) {
    var i = this.collection.indexOf(v.model) + 1;
    if(i >= this.collection.length)
        i = 0;
    this.child_views[i].enter_edit_mode(); // This method enables the <input>
}

デモ: http: //jsfiddle.net/ambiguous/WeCRW/

これの変形は、への参照をsに追加してから、RowsViewRowView直接tab_next呼び出すことthis.parent_view.edit_next()です。


もう1つのオプションは、keydownハンドラーを内に配置することRowsViewです。RowViewこれにより、との間に少しの結合が追加されますがRowsView、この場合はおそらく大きな問題ではありませんが、イベントソリューションよりも少し醜いです。

var RowsView = Backbone.View.extend({
    //...
    events: {
        'keydown input': 'tab_next'
    },
    render: function() {
        this.child_views = this.collection.map(function(m, i) {
            var v = new RowView({ model: m });
            this.$el.append(v.render().el);
            v.$el.data('model-index', i); // You could look at the siblings instead...
            return v;
        }, this);
        return this;
    },
    tab_next: function(e) {
        if(e.keyCode != 9)
            return true;
        var i = $(e.target).closest('li').data('model-index') + 1;
        if(i >= this.collection.length)
            i = 0;
        this.child_views[i].enter_edit_mode();
        return false;
    }
});

デモ: http: //jsfiddle.net/ambiguous/ZnxZv/

于 2012-07-13T20:51:52.633 に答える