Question

I found backbone.js a couple of days ago, and i found out its a pretty code tool for javascript development though my javascript skill aren't great. However after reading the documentation, i decided to code a simple contact app. I save the contact data on browser localstorage. This is code // Source Code for my contacts app

$(function() {


    //Contact Model
    Contact = Backbone.Model.extend({
        //Contact Defaults
        defaults : {
            first_name : 'First Name',
            last_name : 'Last Name',
            phone : 'Phone Number'
        },
        //Constructor(intialize)
        //Ensuring each contact has a first_name,last_name,phone
        intialize: function(){
            if(!this.get("first_name")) {
                this.set({"first_name":this.defaults.first_name});
            }
            if(!this.get("last_name")) {
                this.set({"last_name":this.defaults.last_name});
            }
            if(!this.get("phone")) {
                this.set({"phone":this.defaults.phone});
            }
        }
    });

    //Contact Collection

    //The collection is backed by localstorage
    ContactList = Backbone.Collection.extend({
        //Model
        model : Contact,
        //Save all contacts in localstorage under the namespace of "contacts"
        localStorage: new Store("contacts")
    });

    //Create global collection of Contacts
    Contacts = new ContactList;

    //Contact View
    ContactView = Backbone.View.extend({
        tagName : "li",

        template: _.template($("#item_template").html()),

        events : {
            "click span.contact-delete": "delete_contact"
        },
        intialize: function(){
            this.bind('change',this.render,this);
            this.bind('destroy',this.remove,this);
        },
        render: function() {
          $(this.el).html(this.template(this.model.toJSON()));
          this.setContent();
          return this;
        },
        setContent: function() {
            var first_name = this.model.get("first_name");
            var last_name = this.model.get("last_name");
            var phone = this.model.get("phone");
            var name = first_name+" "+last_name;
            this.$('.contact-name').html(name);
            this.$('.contact-phone').html(phone);
        },
        remove: function() {
              $(this.el).remove();
        },
        delete_contact: function() {
            this.model.destroy();
        }
    });

    //The Application
    AppView = Backbone.View.extend({

        el: $("#contact-app"),

        events : {
            "click #new-contact #save-button": "createContact"
        },
        intialize: function() {

            Contacts.bind("add", this.addOne, this);
            Contacts.bind("reset", this.addAll, this);          
            Contacts.fetch();
        },

        // Add a single contact item to the list by creating a view for it, and
        // appending its element to the `<ul>`.
        addOne: function(contact) {
          var view = new ContactView({model: contact});
          this.$("#contact-list").append(view.render().el);
        },
        // Add all items in the **Contacts** collection at once.
        addAll: function() {
          Contacts.each(this.addOne);
        },
        // Generate the attributes for a new Contact item.
        newAttributes: function() {
          return {
            first_name : this.$('#first_name').val(),
            last_name : this.$('#last_name').val(),
            phone : this.$('#phone').val()
          };
        },
        createContact: function() {
            Contacts.create(this.newAttributes());
            //Reset Form
            this.$('#first_name').val('');
            this.$('#last_name').val('');
            this.$('#phone').val('');
        }
    });

    // Finally,kick things off by creating the **App**.
     var App = new AppView;
});

And this is my html source

   <div id="contact-app">

        <div class="title">
            <h1>Contacts App</h1>
        </div>

        <div class="content">

            <div id="new-contact">
                <input name="first_name" placeholder="First Name" type="text" id="first_name"/>
                <input name="last_name" placeholder="Last Name" type="text" id="last_name" />
                <input name="phone" placeholder="Phone Number" type="text" id="phone" />
                <button id="save-button">Create Contact</button>
            </div>

            <div id="contacts">
                <ul id="contact-list">
                </ul>
            </div>

            <div id="contact-stats"></div>

        </div>

    </div>
    <script type="text/template" id="item_template">
    <div class="contact">
        <div class="contact-name"></div>
        <div class="contact-phone"><div>
        <span class="contact-delete"></span>
    </div>
  </script>

The contact data gets saved in the local storage, which i can see via firebug but the view is not updated. Am new to backbone.js. What is the problem, there are no javascript errors.

Was it helpful?

Solution

Try using "add" instead of 'create' for adding models to the collection (I don't think the 'add' event is being fired by the 'create' method).

Instead of

    Contacts.create(this.newAttributes());

Use

   Contacts.add(this.newAttributes());

To save the model to local storage you can call the save method

addOne: function(contact) {

      var view = new ContactView({model: contact});
      contact.save();
      this.$("#contact-list").append(view.render().el);
    }, 

EDIT:

Another thing check the spelling of your "intialize" method i think it should be "initialize".

Here's a jsFiddle, I'm not saving it to localStorage in the jsfiddle, but that should work by you.

OTHER TIPS

On the model, the defaults should take care of the default values, the initialize functions are probably not needed; someone correct me on this if i'm wrong.

On your ContactView, you may have to change your render line to this in your initialize method:

this.model.bind('change', _.bind(this.render, this));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top