Backbone.js:如何最有效地将我共享的 Mustache 模板应用到 View 的 el?

标签 backbone.js dry encapsulation mustache

Backbone JS View 非常“有用”,因为它们总是为您创建一个 DOM 节点,带有可配置的标签、id 和类。这是非常好的和包容的,但我发现它造成了一个不幸的情况:View 创建的 DOM 节点是一个隐藏的模板。

在我们当前的项目中,这对我来说变得很明显,我们在前端和后端之间共享 Mustache 模板。使用 Backbone,当你想要一个看起来像这样的 DOM 时:

<section class="note">
  <textarea>
  ...
  </textarea>

  <input type="button" class="save-button" value="Save">
  <input type="button" class="cancel-button" value="Cancel">
</section>

您最终会创建如下所示的模板:

<textarea>
{{& content}}
</textarea>

<input type="button" class="save-button" value="Save">
<input type="button" class="cancel-button" value="Cancel">

但现在您的模板与主干 View 上的 secret 根节点模板相关联,需要在服务器端进行复制。干封装到此为止!

除了在渲染时对渲染模板使用 setElement() 之外,我没有看到一个立即明显的方法来解决这个问题,但这会带来其他问题,比如必须替换在每次 render() 之后,DOM 中新呈现的子树。

你是如何解决这个问题的?

最佳答案

这是一个有趣的问题。我以前从来没有解决过这个特殊问题,但我尝试了几个选项,我想我找到了一个我喜欢的。

首先,这是代码:

//A base view which assumes the root element of its
//template (string, DOM node or $) as its el.
var RootlessView = Backbone.View.extend({

    //override the view constructor
    constructor: function(options) {

        //template can be provided by constructor argument or
        //as a subclass prototype property
        var template = options.template || this.template;

        //create a detached DOM node out of the template HTML
        var $el = Backbone.$(template).clone()

        //set the view's template to the inner html of the element
        this.template = $el.html(); 

        //set the element to the template root node and empty it
        this.el = $el.empty()[0];

        //call the superclass constructor
        Backbone.View.prototype.constructor.apply(this, arguments);
    }
});

本质上,您定义了一个基础 View ,它期望每个派生 View 都有一个 template 属性,或者将一个 template 作为选项散列中的参数。模板可以是字符串、DOM 节点或 jQuery/Zepto 包装的 DOM 节点。 View 假定模板的根节点为其 el,并将 template 属性重新定义为根节点的 contents

您可以将其用作普通 View :

var View = RootlessView.extend({
    template: templateHtml,
    render: function() {
        this.$el.html(Mustache.render(this.template, this.model));
        return this;
    }
}); 

el 属性从一开始就可用,它不会在重新渲染时分离和重新附加。正常 Backbone.View 行为的唯一异常(exception)是,如果您定义了 idcssClasstagName 属性或参数,它们将被忽略,因为模板提供了根元素。

这没有经过广泛的测试,但似乎通过了大多数简单的测试用例。我能想到的唯一缺点是 template html 字符串存储在每个 View 实例(而不是原型(prototype))上,浪费了宝贵的内存字节,但这也不难解决.

这是一个working demo on JSFiddle .

关于Backbone.js:如何最有效地将我共享的 Mustache 模板应用到 View 的 el?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14470014/

相关文章:

javascript - Backbone.js 再次渲染 View 还是重新创建?

c - 非调试配置中未使用的变量

php - 使用 SYmfony 在 PHP 中处理 "Undefined Index"

c++ - 声明后添加好友类

Typescript 允许对 mixins 使用适当的多重继承,但无法创建声明文件

javascript - Backbone.js View 中的多个模型

inheritance - 如何在使用 Coffeescript 时扩展主干模型并保持默认值

javascript - 主干模型在错误验证时设置值

php - 如何减少 IF 语句的数量?

types - 在导出的签名中隐藏私有(private)类型