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);

也就是说,最终期望 content 的空容器

显然,这种渲染和附加模式是 Backbone 的核心概念,并且有容器来放置内容似乎是绝对必要的。

我的同事的问题是,是否可以使用更多的服务器端 MVC 模板模式,在这种模式中您不需要任何空容器:

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

在这种情况下,假设开发人员代表一组模型,而宠物代表一组模型。他们每个人都需要自己的视图/子视图,并附有事件。

我假设更经典的服务器端 MVC 模板系统的问题是视图及其相关模板将丢失对 Backbone 所依赖的上下文限制和事件绑定的细粒度控制。

我见过的所有 Backbone 示例/文档都使用这种“空容器/附加”模式。是否有可能以其他方式做事?为什么或者为什么不?

4

1 回答 1

2

Backbone 视图需要一个 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/ 。

当然,你可以更进一步,重新提出你的观点,这些问题可能会帮助你进一步挖掘

Backbone,而不是包装BackboneJS 渲染问题的“this.el”

于 2013-02-02T09:29:47.403 回答