【问题标题】:Backbone Underscore Template骨干下划线模板
【发布时间】:2012-07-25 20:51:02
【问题描述】:

所以我正在检查与最新骨干网/下划线版本相关的更改。之前我有一个使用 BB 0.5.2 并下划线 1.1.7 运行的项目。我注意到在新版本的视图中定义模板属性有些奇怪,这让我对升级有所保留。

在我当前的版本中,我会这样定义一个视图:

var MyView = Backbone.View.extend({
  template: _.template($('#exampleTemplate').html()),
  initialize: function() {...},
  render: function() { $(this.el).html(this.template(someObjectParam)); },
});

但是,如果我尝试以相同的方式工作,以简化的 todo 克隆尝试为例,我会设置一个带有内联脚本模板的 html,如下所示:

<script>
  $(document).ready(function() {
    app.init();
  });
</script>

<script type="text/template" id="itemViewTemplate">
  <div class="item">
    <input type="checkbox" name="isComplete" value="<%= item.value %>"/>
    <span class="description"><%= item.description %></span>
  </div>
</script>

在我包含的 JS 文件中,我有:

var ItemView = Backbone.View.extend({   
  el: 'body',

  // Below causes error in underscore template, as the jquery object .html() call
  // returns null.  Commenting will allow script to work as expected.
  templateProp: _.template($('#itemViewTemplate').html()),  

  initialize: function() {
    // Same call to retrieve template html, returns expected template content.
    console.log($('#itemViewTemplate').html());  

    // Defining view template property inside here and calling it, 
    // properly renders.
    this.template = _.template($('#itemViewTemplate').html());
    this.$el.html(this.template({item: {value: 1, description: 'Something'}}));
  },
});

var app = {
  init: function() {
    console.log('Fire up the app');
    var itemView = new ItemView();
  }
}

所以我很困惑为什么定义模板属性会直接导致检索模板 html 的调用返回空值,从而破坏了定义下划线模板对象的尝试(满口)。但是,如果定义是在初始化函数中完成的,则检索模板 html 的调用会正确找到模板,因此可以将其内容传递给下划线模板。有人看到我可能缺少的东西吗?

提前致谢!

【问题讨论】:

  • 有趣的是,直接复制和粘贴当前 TODO 的主干应用程序,不会遇到同样的问题。莫名其妙。

标签: backbone.js underscore.js


【解决方案1】:

如果这样:

var ItemView = Backbone.View.extend({   
  //...
  templateProp: _.template($('#itemViewTemplate').html()),
  //...
});

失败是因为$('#itemViewTemplate').html()null,那么你有一个简单的计时问题:你试图在#itemViewTemplate 存在之前读取它的内容。您的旧版本应该会遇到完全相同的问题。

要么确保所有内容都以正确的顺序加载(即您的视图您的模板&lt;script&gt;s),或者在您的视图initialize 中编译模板。您可以在视图的prototype 中检查templateProp,如果需要,仅在首次使用时编译它:

initialize: function() {
    if(!this.constructor.prototype.template)
        this.constructor.prototype.template = _.template($('#itemViewTemplate').html());
    //...
}

演示:http://jsfiddle.net/ambiguous/HmP8U/

【讨论】:

  • 你在时间问题上是对的,哦!尽管确切的解决方法是将包含的脚本包装在一个自执行函数中,以便它在文档准备好时运行。傻我!感谢您的提示!
  • @aztechy:不是自执行函数,而是$(document).ready(function() { ... });(又名$(function() { ... });)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多