如何正确存储javascript模板,以便多次实例化

Mat*_*odd 9 javascript backbone.js underscore.js

我正在使用Backbone,因此使用Underscore来渲染我的模板.我的模板在<script>标签中呈现,然后我使用jQuery来获取他们的html.我的主干视图如下所示:

App.ItemView = Backbone.View.extend({
    className:'well',

    events: {
        'click .continue': 'handleContinueClick',
    },

    initialize: function() {
        this.template = _.template($("#ItemTemplate").html())
        this.render()
    },

    render: function() {
        $(this.el).html(this.template({model:this.model}))
    },

    handleContinueClick: function(e) {
        alert('Clicked!')
    }
})
Run Code Online (Sandbox Code Playgroud)

我的问题是我只想为这个特定类型的视图只抓取一次html,这样如果我有很多项目,那么每次都不会在html中搜索这个模板.

基本上我如何在ItemView对象级别(不是视图的实例)正确存储模板变量,记住html的检索必须等到页面加载后(这样我才能保证模板html可用).

Der*_*ley 16

您可以构建一个非常简单的对象来缓存模板:


TemplateCache = {
  get: function(selector){
    if (!this.templates){ this.templates = {}; }

    var template = this.templates[selector];
    if (!template){
      var tmpl = $(selector).html();
      template = _.template(tmpl);
      this.templates[selector] = template;
    }

    return template;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的视图中,您可以调用TemplateCache.get并传入模板选择器.


Backbone.View.extend({
  template: "#ItemTemplate",

  render: function(){
    var template = TemplateCache.get(this.template);
    var html = template(this.model.toJSON());
    this.$el.html(html);
  }
});
Run Code Online (Sandbox Code Playgroud)

第一次调用TemplateCache.get给定的选择器时,它将从DOM加载它.获取模板的任何后续调用都将从缓存版本加载它,并阻止额外的DOM访问调用.

FWIW:TemplateCache我的Backbone.Marionette框架中有一个更强大的对象版本:https://github.com/derickbailey/backbone.marionette

  • @JayC只是为了好玩,我整理了一个JSPerf测试:http://jsperf.com/dom-select-vs-cache ...我不知道这个测试是否完美,但它应该说明不同之处.在大多数实际使用案例中,差异是否明显......也许不是. (3认同)
  • 只是为了澄清:为什么不缓存模板构造函数而不是html字符串本身? (2认同)

abr*_*ham 5

我见过的大多数Backbone示例都是这样做的.这将只遍历DOM一次,以在页面完成加载时解析模板,并为每个页面使用它new ItemView().

App.ItemView = Backbone.View.extend({
    template: _.template($("#ItemTemplate").html()),

    className:'well',

    events: {
        'click .continue': 'handleContinueClick',
    },

    ...
});
Run Code Online (Sandbox Code Playgroud)

http://backbonejs.org/docs/todos.html#section-21

  • 这样做有危险,因为您的模板可能根本无法加载.http://lostechies.com/derickbailey/2011/11/09/backbone-js-object-literals-views-events-jquery-and-el/ (3认同)
  • 如果此代码出现在模板之后(因此在加载模板之后),那么应该没有任何危险.简单易读.这是我的首选技术. (2认同)