使用 Backbone 动态创建的 .el 是否将模板与视图耦合?



我正在学习如何在我正在进行的项目中使用Backbone,并对在Backbone中解耦视图和模板的最佳实践有疑问。特别是动态生成的CCD_ 1和CCD_。

在文档中,它说View.el is created from the view's tagName, className, id and attributes properties, if specified. If not, el is an empty div.

问题1:

在设置视图的属性、id和className时,这是否不会将视图和模板文件高度耦合到这样一个点,即如果设计者想要调整模板,他们需要访问视图?

例如,我有一个jQueryMobile列表,其中的属性和类名决定了列表的外观:

<li data-corners="false" data-shadow="false" data-iconshadow="true" data-wrapperels="div" data-icon="arrow-r" data-iconpos="right" data-theme="c"
class="ui-btn ui-li ui-li-has-thumb ui-btn-up-c"></li>

如果我使用Backbone视图的tagName、attributes和className属性,那么所有这些都将存储在view文件中,而不是模板中。这不是一个糟糕的做法,还是我错过了什么?

问题2

为了避免上述情况,我是:

A。根本不使用View.el或相关属性(tagName、attributes等),而是将其直接放在模板文件中。

B。使用underscore.template()编译我的模板,并通过调用render()函数将其注入View.$el属性:

View.$el.html(_.template(template, data))

当它是根视图时,将目标id传递给view构造函数,并在我的渲染函数中调用:

$(this.target).append(View.$el.html());

或者,如果是一个视图调用另一个视图:

$("#target_id").append(view.render.$el.html());

这是一种可以的方法/实践吗?还是我应该使用其他一些最佳实践?

1)el并不是真正用于您的模板(即不是在渲染之前),而是用于将视图绑定到DOM。定义视图时,可以通过指定View.el0将selector传递给视图

var MyAwesomeView = Backbone.View.extend({
    el: '#some_node',
    ...
});

或者当您实例化视图时

var myView = new MyAwesomeView({
  el: '#some_other_node',
  ...
});

您也可以像@bentermanswer中那样传递$选择器,两者都会给您几乎相同的结果。

也可以完全不指定任何selector,而只能指定tagNameclassNameid。看看这个

源代码片段:https://github.com/jashkenas/backbone/blob/master/backbone.js#L1092-L1106

对于您的示例,您可以将li作为模板,而不是将视图附加到li,而是将其附加到您的ulol 之一

2)我想我已经解释了A。至于B,看看这个很棒的演示:http://amy.palamounta.in/2013/04/12/unsuck-your-backbone/

据我所知,设计者可以更改模板。您只需将模板注入您的主干视图,例如在初始化时通过其ID调用模板。然后,通过将视图插入到由"el"标识的父容器中来呈现视图,该父容器可能是类或id。

若要更改视图的样式,只需更改模板即可。这种方法将视图的逻辑和外观分开。

<script id="templ" type="text/html">
    <li class="fancy-styling">A designer made me.</li>
</script>
<script type="text/javascript" src="jQuery.js"></script>
<script type="text/javascript" src="underscore.js"></script>
<script type="text/javascript" src="backbone.js"></script>
<script type="text/javascript">
    (function ($) {
        var myView = Backbone.View.extend({
                initialize: function (options) {
                    this.template = options.template;
                },
                render: function () {
                    var compiled = _.template(this.template);
                    this.$el.html(compiled({}));
                    return this;
                }
            }),
            view = new myView({
                el: $('#links'),
                template: $('#templ').html()
            });
        view.render();
    })(jQuery);
</script>

所有属性都可以描述为这样的函数,因此您可以在渲染之前对其进行操作:

var MyView = Backbone.View.extend({
    className: function() {
        return this.options.dynamicClassName + ' always-here';
    },
    id: function() {
        return this.options.dynamicId;
    },
    tagName: function() {
        return this.options.dynamicTagName;
    },
    render: function() {
        return this;
    }
});
var myView = new MyView({
    dynamicClassName: 'test',
    dynamicTagName: 'li',
    dynamicTd: 'blah'
});

您也可以直接传入您想要的内容,而无需在视图中定义:

var myView = var myView = new MyView({
    className: 'test',
    tagName: 'li',
    id: 'blah'
});

最新更新