0

I started learning Backbone JS, I just had some doubt.

Iam creating this with my below code I mean this user form http://backbonetutorials.com/videos/beginner/#/new

Scenario 1 Updating User only Once, BUT Scenario 2 Saving user more than once, I mean same user details getting stored more than once in DB, in short its triggering 'submit' event more than once, WHY is that happening like that? Whats happening in background in case of below 2 scenarios?

Below is the code:

<html>
<head>
<link rel="stylesheet"
    href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
<script type="text/javascript">
    /*$.getJSON('api/users/1',function(data){

        console.log(data);
    });*/
</script>


</head>

<body>

    <div class="container">
        <h1> User Manager</h1>
        <hr/>       
        <div class="page"></div>
    </div>

    <script type="text/template" id="user-list-template">
        <a href="#/new" class="btn btn-primary">New User</a>
        <hr/>
        <table class="table stripped">
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Age</th>
                </tr>
            </thead>
            <tbody>
                <% _.each(users, function(user){  %>
                <tr>
                    <td><%= user.get('firstName') %></td>
                    <td><%= user.get('lastName') %></td>
                    <td><%= user.get('age') %></td>
                </tr>
                <% }); %>                       
            </tbody>
        </table>
    </script>

    <script type="text/template" id="add-user-template">
        <form class="add-user-form" >
            <legend><%= user ? 'Update' : 'Create' %>  User</legend>
            <label>First Name</label>
            <input type="text" name="firstname" id="firstname" value="<%= user ? user.get('firstName') : '' %>"/>
            <label>Last Name</label>
            <input type="text" name="lastname" id="lastname" value="<%= user ? user.get('lastName') : '' %>" />
            <label>Age</label>  
            <input type="text" name="age" id="age" value="<%= user ? user.get('age') : '' %>"/>
            <hr/>
            <% if(user) { %>
                <input type="hidden" id="id" value="<%= user.id %>">
            <% }; %>
            <input type="submit" value="<%= user ? 'Update' : 'Create' %> User" />
        </form>
    </script>


<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>

<script type="text/javascript">

    var UsersList = Backbone.Collection.extend({
        url: 'api/users'
    });

    var User = Backbone.Model.extend({
        urlRoot: 'api/users'
    });

    var UsersListView = Backbone.View.extend({
        el: '.page',
        render: function(){
                var that = this;
                var users = new UsersList();
                users.fetch({
                    success: function(usersList){
                    var template = _.template($('#user-list-template').html())({users: usersList.models});
                    that.$el.html(template);
                }
            });         
        }
    });

    var AddUserView = Backbone.View.extend({
        el: '.page',
        render: function(){
            console.log('Creating User...');
            var template = _.template($('#add-user-template').html())({user:null});
            this.$el.html(template);
        },
        events: {
            'submit .add-user-form': 'saveOrUpdateUser' 
        },
        saveOrUpdateUser: function(e){
            e.preventDefault();
            var userDetails = {firstName: $('#firstname').val(), lastName: $('#lastname').val(), age: $('#age').val()};
            var user = new User();
            user.save(userDetails,{
                success: function(user){
                    console.log('INSIDE SUCCESS..');
                    router.navigate('',{trigger: 'true'});
                }
            }); 
        }       
    });

    var Router = Backbone.Router.extend({
        routes:{
            '':'home',
            'new':'addUser'
        }       
    });

SCENARIO 1: // Firing Save only Once, I mean its working perfectly.

var usersListView = new UsersListView();
    var addUserView = new AddUserView();

    var router = new Router();
    router.on('route:home',function(){
        usersListView.render();
    });
    router.on('route:addUser',function(){
        addUserView.render();
    });


    Backbone.history.start();

SCENARIO 2: // Saving User Data More than Once, Why???

var router = new Router();
    router.on('route:home',function(){
        var usersListView = new UsersListView();
        usersListView.render();
    });
    router.on('route:addUser',function(){
        var addUserView = new AddUserView();
        addUserView.render();
    });


    Backbone.history.start();
user3815806
  • 243
  • 5
  • 15

1 Answers1

1

Lol. I just answered this question yesterday. Looks like someone has to alert the author of his tutorial that he's creating Zombie Views!

To answer you question, the reason the first scenario works is because you create only one view and then use your router to render that same view. But if you'll look at Scenario 2 there every subsequent time you follow the route #new you create another AddUserView view and you're rendering that view. All your past views do not go away because they are still listening to events in some element of the DOM they manage. In your case, you have

events: {
  'submit .add-user-form': 'saveOrUpdateUser' 
}

so each rendered view is listening to the <submit> button element.

Check out this answer, Backbone js Model Save more than once, for more details. And of course, don't miss Derick Bailey's classic article Zombies! RUN! (Managing Page Transitions In Backbone Apps). (BTW, using Derick's Marionette, a very active, stable and well supported Backbone Framework you'll have plenty of tools at your disposal to help you avoid zombie views).

Community
  • 1
  • 1
seebiscuit
  • 4,905
  • 5
  • 31
  • 47
  • At first, thanks for your detailed explanation.. But one doubt: why in DOM view object doesn't exists when its still attached to events? – user3815806 Jan 22 '15 at 07:31
  • I think you're asking, how can a view be removed from the DOM even if it has events bound to a section if the DOM? That's a pretty good question, one that requires way more knowledge than I have. – seebiscuit Jan 22 '15 at 23:18