骨干下划线模板

时间:2012-07-25 20:51:03

标签: backbone.js underscore.js

所以我查看了与最新骨干/下划线版本相关的更改。之前我有一个运行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)); },
});

但是,如果我尝试以相同的方式工作,使用简化的待办事项克隆尝试作为示例,我设置了一个带有内联脚本模板的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以返回空值,从而破坏了定义下划线模板对象的尝试(满口)。但是,如果定义是在initialize函数内完成的,则正确检索模板html的调用会找到模板,因此可以将其内容传递给下划线模板。有人看到我可能遗失的东西吗?

提前致谢!

1 个答案:

答案 0 :(得分:3)

如果:

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

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

确保以正确的顺序加载所有内容(例如模板<script>后的视图<)>或者在视图的initialize中编译模板。您可以在视图的templateProp中检查prototype,并且只在您首次使用时进行编译:

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

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