2

仲間のフロントエンド開発者が私にこの質問を投げかけました、そして私は私のスタンスを明確にする方法が正確にわかりませんでした、しかし彼は私に考えさせました:

したがって、Backbone(またはBackbone.Marionette)の規則では、テンプレートに関連付けられたビューをレンダリングしてから、結果のビューの構築/合成されたHTMLを既存のコンテナーにダンプまたは追加します。

this.$el.append(this.subview.render().$el);

ただし、もちろん、これには、この新しくレンダリングされたビューをにダンプするために、すでにレンダリングされているページ上のDOM要素が必要です。これにより、次のような現象が発生します。

<ul id="scheduler-loadroutegroups" class="full-height"></ul>

また

collectionView.$("#scheduler-loadroutegroups").append(itemView.el);

つまり、最終的にコンテンツを期待する空のコンテナです。

明らかに、このレンダリングと追加のパターンはBackboneのコアコンセプトであり、コンテンツを配置するためのコンテナーを持つことは絶対に不可欠であるように思われます。

私の同僚の質問は、空のコンテナー必要としない、よりサーバー側のMVCテンプレートパターンを利用できるかどうかでした。

<ul id="scheduler-loadroutegroups" class="full-height">
    {{#developers}}
        <ul>
            {{#pets}}
                <li>{{name}}</li>
            {{/pets}}
        </ul>
    {{/developers}}
</ul>

この例では、開発者がモデルのコレクションを表し、ペットがモデルのコレクションを表すとします。それぞれに、イベントが添付された独自のビュー/サブビューが必要になります。

より古典的なサーバー側のMVCテンプレートシステムの問題は、ビューとそれに関連するテンプレートで、Backboneが依存するコンテキスト制限とイベントバインディングをきめ細かく制御できないことだと思います。

私が見たすべてのバックボーンの例/ドキュメントは、この「空のコンテナ/追加」パターンを使用しています。他の方法で何かをすることは可能ですか?なぜまたはなぜそうではないのですか?

4

1 に答える 1

2

バックボーンビューにはDOM要素が必要であり、その作成を容易にする属性を提供するところまで行きますが、テンプレートエンジンまたはDOM操作を使用する必要はありません。既存のマークアップ構造を使用できます。ビューを正しいDOMノードにアタッチするだけです。

レンダリングされたHTMLが次のようになっていると仮定します

<ul id='scheduler-loadroutegroups'>
    <li id='d1'>
    <ul>
        <li id='p1'>P1</li>
        <li id='p2'>P2</li>
    </ul>
    </li>
    <li id='d2'>
    <ul>
        <li id='p3'>P3</li>
        <li id='p4'>P4</li>
    </ul>
    </li>
</ul>

関連するDOMノードを取得し、サブビューを関連付けるビューを使用できます。サブビュー自体がDOMノードなどを設定します。

var DevListView = Backbone.View.extend({
    initialize: function() {
        this.inject();
    },

    inject: function() {
        var $el = this.$el;

        this.collection.each(function (model) {
            var subview = new DevView({
                el: $el.find("#d" + model.id),
                model: model
            });
        });
    }
});

var DevView = Backbone.View.extend({
    initialize: function() {
        this.inject();
    },

    inject: function() {
        var $el = this.$el;

        this.model.pets.each(function (model) {
            var subview = new PetView({
                el: $el.find("#p" + model.id),
                model: model
            });
        });
    }
});

var PetView = Backbone.View.extend({
    events: {
        'click ': function () {
            this.$el.toggleClass('selected');

            var msg = '<p>Pet '+this.model.get('id')+'</p>';
            $('body').append(msg);
        }
    }
});

次に、関連するデータを使用してルートビューを呼び出し、初期化メソッドが残りを実行します。

var Developer = Backbone.Model.extend({
    initialize: function () {
        this.pets = new Backbone.Collection(this.get('pets'));
    },
    parse: function (data) {
        this.pets.reset(data.pets);
        return data;
    }
});
var Developers = Backbone.Collection.extend({
    model: Developer
});
var v = new DevListView({
    el: '#scheduler-loadroutegroups',
    collection: devs
});

デモについては、 http://jsfiddle.net/3xNHj/を参照してください。

もちろん、さらに進んで自分の意見を再現することもできます。これらの質問は、さらに掘り下げるのに役立つ可能性があります。

BackboneJSレンダリングの問題をラップする「this.el」ではなくバックボーン

于 2013-02-02T09:29:47.403 に答える