1

私はバックボーンを初めて使用し、オブジェクトのコレクションとそれらをリストとして表示するビューを持っています。オブジェクトがコレクションに追加されるたびに、ビューが再レンダリングされるように設定されています。一度に 20 個のアイテムをコレクションに追加すると、最後のアイテムが追加された後に 1 回レンダリングするだけでよいのに、20 回レンダリングされるため、これは非常に非効率的です。コレクションへの追加が完了するまでバックボーンのレンダリングを保留するにはどうすればよいですか?

これが私のコードです:

<html>
    <head>
        <meta charset="utf-8" />
        <title>Looking At Underscore.js Templates</title>
    </head>
    <body>
        <script type="text/template" class="template">
            <ul id="petlist">
                <% _.each(model.pets, function(pet) { %>
                    <li><%- pet.name %> (<%- pet.type %>)</li>
                <% }); %>
            </ul>
        </script>

        <div id="container"/>

        <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
        <script type="text/javascript" src="http://underscorejs.org/underscore.js"></script>
        <script src="http://backbonejs.org/backbone-min.js"></script>
        <script type="text/javascript">

            var serviceData = [
                {
                    name: "Peaches",
                    type: "dog"
                },

                {
                    name: "Wellington",
                    type: "cat"
                },

                {
                    name: "Beefy",
                    type: "dog"
                }
            ];

            $(document).ready(function() {
                var Pet = Backbone.Model.extend({ 
                    name: null,
                    type: null
                });

                var Pets = Backbone.Collection.extend();

                var AppView = Backbone.View.extend({
                    updateUi: function(model) {
                        _.templateSettings.variable = "model";
                        var template = _.template($("script.template").html());
                        var model = { pets: model.collection.toJSON() };
                        var html = template(model);
                        $("#container").html(html);
                    }
                });

                var pets = new Pets();
                var av = new AppView();
                pets.bind("add", av.updateUi);
                pets.set(serviceData);
            });

        </script>
    </body>
</html>
4

3 に答える 3

4

You could also create an extra method called, lets say, add. So, if you add a new object, the application just adds a single object instead of rendering the hole collection again.

Somethin like this:

App.Model = Backbone.Model.extend();

App.Collection = Backbone.Collection.extend({
   model: App.Model
});

App.CollectionView = Backbone.View.extend({
   tagName: 'ul',
   render: function(){
     this.collection.each(function(model){
        var objView = new App.ModelView({ model: model });
        this.$el.append( objView.render().el );
     });
     return this;
   },

   showAddForm: function(){
     // Here you show the form to add another object to the collection
   },

   save: function(){
     // Take form's data into an object/array, then add it to the collection
     var formData = {
         type: $('select[name=type]').val(),
         name $('input[name=name]').val()
     };
     // Once added to the collection, take the object/array and...
     this.addElement(formData);
   },

   addElement: function(model){
     var modView = new App.ModelView({ model: model });
     this.$el.append( modView.render().el );
   }
 });

 App.ModelView = Backbone.View.extend({
    tagName: 'li',
    template: _.template( "<li><%= name %> (<%= type %>)</li>" ),

    render: function(){
       this.$el.html( this.template( this.model.toJSON() ) );
       return this;
    }
 });

Do you get the idea? When you render the hole collection, the collectionView render method calls a modelView for each object/pet. So, this way, when you get the info of a new pet/object you can just create an instance of ModelView, and append it to the actual rendered view.

Hope it helps.

于 2013-04-05T20:37:36.550 に答える
1

次のこともできます。

pets.set(serviceData, { silent: true });
pets.trigger('add', pets);

そして、av.updateUi を変更して、コレクション全体で動作し、一度に HTML を作成しますが、この場合、「追加」イベントよりも「リセット」イベントの方がおそらく適切です。

于 2013-04-05T20:49:15.467 に答える