简体   繁体   English

骨干列表子视图

[英]Backbone Sub-View for List

I am having a hard time understanding sub-views with Backbone and am trying to learn how to use them. 我很难理解Backbone的子视图,并试图学习如何使用它们。

I want to create a simple unordered list using a main view for the container, and a sub-view for each list item. 我想使用容器的主视图和每个列表项的子视图创建一个简单的无序列表。

Here is a Fiddle to what I have currently: http://jsfiddle.net/LrZrJ/ 这是我目前所用的小提琴: http : //jsfiddle.net/LrZrJ/

Here is the HTML I want to see in the end: 这是我最后想要看到的HTML:

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

Here is my JavaScript: 这是我的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();

Here's my HTML: 这是我的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>

You're almost there. 你快到了。 You have two problems right here: 您在这里有两个问题:

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

First of all, jQuery's html function replaces everything: 首先,jQuery的html函数取代了所有内容:

When .html() is used to set an element's content, any content that was in that element is completely replaced by the new content. 使用.html()设置元素的内容时,该元素中的所有内容都将被新内容完全替换。

That means that your second .html call: 这意味着您的第二个.html调用:

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

overwrites everything from the first one. 从第一个覆盖所有内容。 You probably want to use append instead, that will just add the <li> to whatever you append to. 您可能想使用append ,它将只是将<li> append到要append到的内容中。 You'll also want to append to the <ul> , not the self.$el ; 您还需要append<ul>而不是self.$el ; Backbone includes a handy this.$ function in your view's for searching within the view's el : Backbone在视图的视图中包含一个方便的this.$函数,用于在视图的el进行搜索:

$ (jQuery) view.$(selector) $(jQuery) view.$(selector)

[...] It's equivalent to running: view.$el.find(selector) [...]等效于运行:view。$ el.find(selector)

So to find the <ul> and put the <li> inside it, you can say this: 因此,要找到<ul>并将<li>放入其中,可以这样说:

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

While I'm here, it is common for a view's render to return this and then the caller would something.append(v.render().el) to get the view onto the page. 当我在这里时,视图的render通常return this ,然后调用者将通过something.append(v.render().el)将视图显示到页面上。 You could use setElement to replace the sub-view's el with your <li> from the template: 您可以使用setElement用模板中的<li>替换子视图的el

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

and then self.$('ul').append(self.item.render().el) in the parent. 然后是父对象中的self.$('ul').append(self.item.render().el)

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

An alternative would be to add tagName: 'li' to ListItem so that Backbone would create an <li> as that view's el and then remove the <li>...</li> from the template. 另一种选择是将tagName: 'li'添加到ListItem以便Backbone将创建一个<li>作为该视图的el ,然后从模板中删除<li>...</li> That would give you a ListItem like this: 那会给你这样的ListItem

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

and an #item template like this: 和如下的#item模板:

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

This structure would (IMO) be more standard than what you're currently working with (but Backbone isn't very opinionated so do what works for you). 这种结构(IMO)会比您目前使用的结构更为标准(但是Backbone并不十分自以为是,因此请为您工作)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM