【问题标题】:Nesting Backbone views with templates使用模板嵌套 Backbone 视图
【发布时间】:2015-10-27 17:06:13
【问题描述】:

我正在尝试嵌套使用把手模板的主干视图。

http://jsfiddle.net/6j4yodz6/6/

我的问题是我不知道如何使用模板,所以外部和内部视图都在使用模板。此外,现在它显示模板的 html:

< li > Title1 - Content #1< /li>
< li > Title2 - Content #2< /li>
< li > Title3 - Content #3< /li> 

HTML:

<script type="text/html" id="ul-template">
    < ul class = "outer" > < /ul>
</script>

<script type="text/html" id="li-template">
    < li > {{attributes.title}} - {{attributes.content}}< /li>
</script>

JAVASCRIPT:

var documents = [
new Backbone.Model({
    title: 'Title1',
    content: 'Content #1'
}),
new Backbone.Model({
    title: 'Title2',
    content: 'Content #2'
}),
new Backbone.Model({
    title: 'Title3',
    content: 'Content #3'
})];

var ContentsView = Backbone.View.extend({
    tagName: 'ul',
    render: function () {
        _(this.collection).each(function (document) {
            //How do you use ul-template?
            this.$el.append(new DocumentListView({
                model: document
            }).render().el);
        }, this);
        return this;
    }
});

var DocumentListView = Backbone.View.extend({
    tagName: 'li',
    events: {
        'click': function () {
            console.log("clicked");
        }
    },
    render: function () {
        var source = $("#li-template").html(); 
        var template = Handlebars.compile(source);
        //This is using the template but is displaying the html.
        this.$el.html(template(this.model));
        return this;
    }
});


$('body').html(new ContentsView({
    collection: documents
}).render().el);

【问题讨论】:

    标签: javascript backbone.js handlebars.js


    【解决方案1】:

    这是一个对您的示例应用程序很有帮助的重写。请注意,如果这只是容器标记,则不需要该模板,使用 tagName 将设置该视图使用的标记。如果父视图确实需要更复杂的视图,我只需渲染一个子视图并将其附加到父视图模板中的元素。

    var documents_data = [{
        title: 'Title1',
        content: 'Content #1'
    },{
        title: 'Title2',
        content: 'Content #2'
    },{
        title: 'Title3',
        content: 'Content #3'
    }];
    
    var documents = new Backbone.Collection(documents_data);
    
    var ContentsView = Backbone.View.extend({
      tagName: 'ul',
      className: 'outer',
      render: function () {
        this.collection.each(this.addOne, this);
        return this;
      },
      addOne: function (document) {
        var documentListView = new DocumentListView({
          model: document
        });
        documentListView.render().$el.appendTo( this.el );
      }
    });
    
    var DocumentListView = Backbone.View.extend({
      tagName: 'li',
      template: Handlebars.compile($("#li-template").html()),
      events: {
        'click': 'onClick'
      },
      render: function () {
        this.$el.html(this.template(this.model));
        return this;
      },
      onClick: function(){
        $(document.body).append("<p>clicked: "+ this.model.get('title') +'</p>' );
      }
    });
    
    var contentsView = new ContentsView({
        collection: documents
    });
    contentsView.render().$el.appendTo( document.body );
    <script src='http://code.jquery.com/jquery.js'></script>
    <script src='http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js'></script>
    <script src='http://backbonejs.org/backbone.js'></script>
    <script src='http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.js'></script>
    
    <script type="text/template" id="li-template">
      {{attributes.title}} - {{attributes.content}}
    </script>

    【讨论】:

      【解决方案2】:

      除了 Yura 的回答,我还发现了类似使用 Marionette 的东西:

      http://jsfiddle.net/e7L822c8/

      HTML:

      <div class="js-page">
      </div>
      
      <script type="text/template" id="ListViewTemplate">
          <h3>Here is a list</h3>
          <ul class="js-list">
      
          </ul>
      </script>
      
      <script type="text/template" id="ItemViewTemplate">
        <%- name %>
      </script>
      

      JAVASCRIPT:

      window.App = new Backbone.Marionette.Application();
      
      App.addRegions({
        mainRegion: '.js-page'
      });
      
      App.start();
      
      var TheModel = Backbone.Model.extend({});
      
      var TheCollection = Backbone.Collection.extend({
          model: TheModel,
      });
      
      var ItemView = Backbone.Marionette.ItemView.extend({
          initialize: function() { 
              console.log('this.model =',this.model.toJSON()); 
              console.log(this);      
          },
      
          tagName: 'li',
      
          className: 'list-item',
      
          template: '#ItemViewTemplate',
      
      
      });
      
      var ListView = Backbone.Marionette.CompositeView.extend({
          tagName: 'div',
      
          className: 'js-list-container',
      
          template: '#ListViewTemplate',
      
          childViewContainer: 'ul',
      
          childView: ItemView
      });
      
      var dataArray = [
          {"name":"FirstObject"},{"name":"SecondObject"},{"name":"ThirdObject"}
      ];
      
      var theCollection = new TheCollection(dataArray);
      var listView = new ListView({collection: theCollection});
      
      App.mainRegion.show(listView);
      

      这显示了如何使用这两个模板。

      【讨论】:

      • 如果你可以使用 Marionette,一定要使用 CollectionViewCompositeView。如果您需要任何示例,我可以在那里为您提供帮助。
      猜你喜欢
      • 1970-01-01
      • 2012-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 2015-10-13
      • 2011-10-30
      • 1970-01-01
      相关资源
      最近更新 更多