如何在不重新渲染BackboneJs的情况下更新视图?

时间:2014-03-31 15:15:24

标签: backbone.js underscore.js backbone-views backbone-model underscore.js-templating

我试图做显而易见的事情,更新模型更改视图(在这种情况下添加了一个新视图)。 它确实有效,但问题是在添加模型时整个视图会被重新渲染。 新数据实际上并没有真正附加到视图中,但几乎所有内容都是使用" html()"重新加载的。方法

您是否知道以更有效的方式解决此问题的方法?

<body>
<div class="page"></div>

    <script type="text/template" id="myTemplate">
        <ul>
            <% for (var i = 0; i < library.length; i++) { %>
                    <li> <%= library[i].title %></li>
                    <li> <%= library[i].artist %></li>
                    <li> <%= library[i].track %></li>  
                <br>
            <% } %>  
        </ul>

        <input id="inputTitle" placeholder="enter title" type="text"> <br>
        <input id="inputArtist" placeholder="enter artist" type="text"> <br>
        <input id="inputTrack" placeholder="enter title" type="number"> <br> 
        <button id="addItem">add</button> 
    </script>

    <script type="text/javascript">

        var Song = Backbone.Model.extend({
            initialize: function()
            {
                this.on('add',function(){
                    albumview.render();
                });
            }
            ,defaults:
            {
                title: "no title",
                artist: "no artist",
                track: 0
            }
        });

        var AlbumView = Backbone.View.extend({
            initialize: function()
            {
                this.render();
            },
            render: function()
            {
                var self = this; 
                var output = _.template($('#myTemplate').html(),{'library': self.collection.toJSON()});

                self.$el.html(output); 
                return self;
            },
            events: 
            { 
                'click #addItem' : 'addItem'
            },
            addItem: function()
            { 
                var TitleValue = $('#inputTitle').val();
                var ArtistValue = $('#inputArtist').val();
                var TrackValue = $('#inputTrack').val();

                var self = this;

                self.collection.push({  
                    title: TitleValue,
                    artist: ArtistValue,
                    track: TrackValue
                });

            }
        });

        var Album = Backbone.Collection.extend({
            model: Song
        });

        var song1 = new Song({
            title: "Trouble on my mind",
            artist: "Pusha-T",
            track: 3
        });

        var song2 = new Song({
            title: "Yonkers",
            artist: "Tyler The Creator",
            track: 2
        });

        var album = new Album([song1,song2]);

        var albumview = new AlbumView({
            el: '.page',
            collection: album
        });

    </script>
</body> 

1 个答案:

答案 0 :(得分:0)

首先,我避免从模型内部调用您的视图渲染方法。其次,你确定要为每首歌创作一个新专辑吗?看起来你的专辑视图保留了对你的专辑集的引用,只需要一个歌曲视图,或者其他一些这样的结构:

var AlbumView = Backbone.View.extend({
    initialize: function () {
        this.listenTo(this.collection, 'reset', this.render);
        this.listenTo(this.collection, 'add', this.addOne);
    },
    render: function () {
        this.addAll();
        return this;
    },
    addAll: function () {
        this.$el.empty();
        this.collection.each(this.addOne, this);
    },
    addOne: function (song) {
        var songView = new SongView({ model: song });
        this.$el.append(songView.render().el);
    }
});

var SongView = Backbone.View.extend({
    render: function () {
        // whatever you would do for just one song
    }
});

这是渲染集合(专辑)视图和项目(歌曲)视图的常用模式。