0

In an attempt to understand Backbone.js more, I made a dummy blog with Backbone.js. I have a 'create post' button. When I click that button it I run:

posts.create({title: makeid(),content: makeid()})

(makeId() just generates some random characters.)
Create should dispatch an add event that I listen for. That add event dispatches only 1 time. I don't know why. I have left a bunch of console.log in the code to show what I tried. On the server side I return all the models on create. I can't seem to find documentation on what the server should return. Here is the app.js

$(function(){

    var Post = Backbone.Model.extend({
        defaults:{
            id: '',
            title : 'Untitled',
            content: 'No content'
        }, 
        urlRoot : '/posts/'
    });

    var Posts = Backbone.Collection.extend({
        model : Post,
        url: '/posts/'
    });

    var posts = new Posts;

    var PostView = Backbone.View.extend({
        tag: 'li',

        template: _.template($("#post-template").html()),

        events: {
            "click .delete-post" : 'deletePost'
        },

        initalize: function(){
            //this.listenTo(this.model, 'change', this.render);
            this.listenTo(this.model, 'destroy', this.remove);
        },

        render: function(){
            this.$el.html(this.template(this.model.toJSON()));
            return this;
        },
        deletePost: function(){
            console.log(this.model);
            this.model.destroy();
            this.$el.remove()
        }
    });

    var AppView = Backbone.View.extend({
        el : $("#home"),

        events:{
            "click #add-post": "addPost"
        },

        initialize: function(){
            this.listenTo(posts, 'add', this.addOne);
            posts.on("add", function(post){
                console.log('post added: ' + post);
            });
            posts.fetch({ update: true });
        },

        addPost:function(){
            console.log('add post')
            posts.create({
                title: makeid(), 
                content: makeid()
            },{success: function(){console.log('success');}
            });
        },

        addOne: function(post){
            console.log('one was added');
            var view = new PostView({model:post});
            this.$("#posts").append(view.render().el);
        },

        render: function(){
            if(posts.length){
                console.log('rendering');
            }
        }
    });
    var appView = new AppView;
});

function makeid()
{
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 5; i++ )
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

Here is my index.html

<!doctype html>
<html>
<head>
    <title>Backbone test</title>
    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css">
</head>
<body>


<div class="container">
    <div class="row">
        <div class="span6" id="home">
            <a href="#" id="add-post" class="btn btn-mini btn-success">add post</a>
            <ul id="posts">
            </ul>
        </div>
    </div>
</div>


<script src="/static/js/jquery.js"></script>
<script src="/static/js/underscore.js"></script>
<script src="/static/js/backbone.js"></script>
<script src="/static/js/bootstrap.js"></script>
<script src="/static/js/app.js"></script>




<script id="post-template" type="text/x-handlebars-template">
<div class="span4">
    <h3>
        <%- title %>
        <br />
        <a href='#' class='btn btn-mini btn-primary'>edit</a>
        <a href='#' class='btn btn-mini btn-danger delete-post'>delete</a>
    </h3>
    <p><%- content %></p>
</div>
</script>

</body>
</html>
4

1 回答 1

1
  • Backbone won't add models with the same id in a collection.
  • Your models have a default id set to an empty string, but any value non undefined or null would yield the same result.
  • The models returned by your server don't have an id set, the default one is used.

What happens is that the first created model takes the default id and is added to the collection. When you create the second one, it is also instantiated with the default id, but it can't be added to the collection. See http://jsfiddle.net/nikoshr/vfEVC/ for a demo.

Either remove the default id or assign one server side to get both instances in your collection.

http://jsfiddle.net/nikoshr/vfEVC/1/

于 2013-05-29T12:36:49.563 回答