使用模板嵌套Backbone视图

时间:2015-10-27 17:06:14

标签: javascript backbone.js handlebars.js

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

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);

2 个答案:

答案 0 :(得分:0)

对于您的示例应用程序,这是一个有希望的有用的重写。请注意,如果只是容器标记,则不需要该模板,使用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>

答案 1 :(得分:0)

除了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);

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