列表的主干子视图

时间:2014-04-04 01:27:15

标签: javascript jquery backbone.js underscore.js underscore.js-templating

我很难理解使用Backbone的子视图,并且我正在尝试学习如何使用它们。

我想使用容器的主视图创建一个简单的无序列表,以及每个列表项的子视图。

这是我目前所掌握的小提琴:http://jsfiddle.net/LrZrJ/

这是我想在最后看到的HTML:

<div class="js-container">
    <h3>Stat = ok</h3>
    <ul>
        <li>Hello world</li>
    </ul>
</div>

这是我的JavaScript:

var TheModel = Backbone.Model.extend({
    default: {
        photos: '',
        stat: ''   
    }
});

var TheCollection = Backbone.Collection.extend({
    model: TheModel,

    url: 'http://api.flickr.com/services/rest/?page=1&api_key=a2978e5ce30c337e3b639172d3e1a0d1&tags=candy&method=flickr.photos.search&per_page=3&format=json&jsoncallback=?'

});

// The main view
var List = Backbone.View.extend({
    el: '.js-container',

    initialize: function () {
        this.collection = new TheCollection();

        this.item = new ListItem();

        return this;
    },

    render: function () {
        var self = this;

        this.collection.fetch({
            dataType: 'jsonp',
            success: function (data) {
                var listTemplate = _.template( $('#listContainer').html(), {
                    collection: self.collection.toJSON()
                });

                self.$el.html(listTemplate);
                self.$el.html( self.item.render() );
            }
        });

        return this;
    }

});

var ListItem = Backbone.View.extend({
    render: function () {
        var itemTemplate = _.template( $('#item').html(), {} );

        return itemTemplate;
    }

});

var myList= new List();
myList.render();

这是我的HTML:

<script type="text/template" id="listContainer">
    <h3>Stat = <%- collection[0].stat %></h3>
    <ul>

    </ul>
</script>

<script type="text/template" id="item">
    <li>Hello world</li>
</script>

<div class="js-container">
</div>

1 个答案:

答案 0 :(得分:2)

你快到了。你有两个问题:

self.$el.html(listTemplate);
self.$el.html( self.item.render() );

首先,jQuery的html function取代了所有内容:

  

.html()用于设置元素的内容时,该元素中的所有内容都将被新内容完全替换。

这意味着您的第二次.html电话:

self.$el.html( self.item.render() );

覆盖第一个的所有内容。您可能希望使用append,而只需将<li>添加到您append的任何内容中。您还需要append<ul>,而不是self.$el; Backbone在您的视图中包含一个方便的this.$函数,用于在视图el中进行搜索:

  

$(jQuery) view.$(selector)

     

[...]它等同于运行:view。$ el.find(selector)

为了找到<ul>并将<li>放入其中,您可以这样说:

self.$('ul').append(self.item.render())

当我在这里时,视图的renderreturn this会很常见,然后调用者会something.append(v.render().el)将视图移到页面上。您可以使用setElement将子视图的el替换为模板中的<li>

var ListItem = Backbone.View.extend({
    render: function () {
        var itemTemplate = _.template( $('#item').html(), {} );
        this.setElement(itemTemplate);
        return this;
    }
});

然后是父母的self.$('ul').append(self.item.render().el)

演示:http://jsfiddle.net/ambiguous/JHV9w/1/

另一种方法是将tagName: 'li'添加到ListItem,以便Backbone可以创建<li>作为该视图的el,然后从<li>...</li>中移除ListItem模板。这样会给你一个var ListItem = Backbone.View.extend({ tagName: 'li', render: function () { var itemTemplate = _.template( $('#item').html(), {} ); this.$el.html(itemTemplate); return this; } });

#item

<script type="text/template" id="item"> Hello world </script> 这样的模板:

{{1}}

这种结构(IMO)比你目前使用的标准更加标准(但Backbone不是很自以为是,所以做对你有用的事情)。

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