【问题标题】:Backbone nested views - child view attributes incorrectly set in the template主干嵌套视图 - 子视图属性在模板中设置不正确
【发布时间】:2012-12-10 05:44:39
【问题描述】:

我正在尝试创建一个包含其他模型集合的主干模型(我们称之为Library)(我们称之为Books)。我提供了一个视图 - LibraryView,它创建了一个书柜的 HTML,其中包含一组由BookView 生成的 HTML 表示的书籍。另外,我使用 Handlebars.js 作为我的模板系统。

我遇到的问题是我的 BookView 在 this.el 元素上返回了奇怪的 html,甚至在我通过 render() 函数之前。

LibraryModel 模型

  var LibraryModel = Backbone.Model.extend({

    initialize: function() {

      var books = new BookCollection();

      _.each(book_data.books, function(value, index) {
        books.add(new Book());
      });

      this.books = books;

    }
  });

LibraryView 视图:

 var LibraryView = Backbone.View.extend({

    el: "#library",

    render: function() {

      var t = this;

      this.model.books.each(function(book, index) {
        //create new view for each Book model in the books collection
        var view = new BookView(book);
        //append HTML produced by the BookView into LibraryView el element
        t.$el.append(view.render().$el);
      });

      return this;  
    },

    initialize: function() {
      //snip
    }
  });

BookView 视图:

  var BookView = Backbone.View.extend({

    render: function() {
      var viewmodel = this.model;
      var source = $("#book-template").html();
      var template = Handlebars.compile(source);
      var html = template(viewmodel.toJSON());

      console.log(html); //prints <div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
      this.$el.html(html);

      return this;  
    },

    initialize: function(book) {
      console.log(this.el.outerHTML); //prints <div test="wtf" anotherTest="123"></div>
      this.model = book;
      this.listenTo(this.model, "change", this.render);
    }
  });

我提供的模板是:&lt;b&gt;{{test}}&lt;/b&gt; {{anotherTest}}

BookModel 模型

  var BookModel = Backbone.Model.extend({
    defaults: {
      test: "wtf",
      anotherTest: 123
    },

    initialize: function() {
        //snip
    }
  });

基本上,我遇到的问题是我的BookView 生成了奇怪的 HTML,其中我的每个模型属性都附加到 Backbone 生成的 div,如下所示:

<div test="wtf" anotherTest="123">
<b>wtf</b> 123
</div>

我没有在代码的其他任何地方设置任何属性 - 这两个值都仅来自默认值。

另外,我确认这不是 Handlebars 正在做的事情,因为模型属性作为 HTML 属性插入到 Backbone 生成的 BookView 模型的 div 中(注意,我没有手动提供 tagName 或 el,我希望 Backbone 为我创建一个 div)。

所以这就是我卡住的地方。我有一个由BookView 为列表中的每个模型生成的完美工作列表,但由于某种原因,Backbone 生成的 div 包装器在其 HTML 属性中包含每个模型属性,如下所示:

<div id="#library">
<div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
<div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
<div test="wtf" anotherTest="123"><b>wtf</b> 123</div>
</div>

我真的很担心这个问题,我怀疑这与我尝试使用 View-in-a-View 的事实有关。

您以前遇到过类似的问题吗?您有 MasterView 呈现 ChildView 集合的 Backbone 应用程序的好例子吗?

【问题讨论】:

    标签: backbone.js handlebars.js mv


    【解决方案1】:

    在创建新的BookViews 时,您正在做一件奇怪的事情。该视图期望BookModel 在其初始化中出现。但是,initialize() 方法总是需要一个按约定称为attributes 的对象。您应该修改您的 BookView 使其匹配:

    var BookView = Backbone.View.extend({
    
        render: function() {
           // keep the same code
        },
    
        initialize: function(attributes) {
            this.listenTo(this.model, "change", this.render);
        }
    });
    

    在你的LibraryView 中你应该使用:

    var view = new BookView({ model : book });
    

    而不是以前的:

    var view = new BookView(film); // which is a typo, and should pass book and not film
    

    所以现在你得到了预期的结果。

    <div id="library">
        <div><b>wtf</b> 123</div>
        <div><b>wtf</b> 123</div>
        <div><b>wtf</b> 123</div>
    </div>
    

    请记住,initialize(attributes) 将使用该映射自动调用 set,因此您不必自己调用 set(attr, value)。考虑到这一点,我们可以理解为什么该视图具有两个属性,实际上是您的两个模型的属性(它们在初始化时是 set())。

    【讨论】:

    • 是的,电影是一个错字。非常感谢!事实上,我缺少的是 {model: book} 而不是将模型直接传递到视图中。
    猜你喜欢
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多