0

所以我正在检查与最新主干/下划线版本相关的更改。之前我有一个使用 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 的调用会正确找到模板,因此可以将其内容传递给下划线模板。有人看到我可能缺少的东西吗?

提前致谢!

4

1 回答 1

3

如果这:

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

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

要么确保所有内容都以正确的顺序加载(即你的视图你的模板之后<script>),要么在你的视图中编译模板initializetemplateProp您可以在您的视图中检查,prototype如果需要,仅在首次使用时编译它:

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

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

于 2012-07-25T21:17:22.473 回答