byCoder
byCoder

Reputation: 9184

Backbone is not fireing events for simple model

I try to save on localStorage some model data (but even try to catch this event, and put to console some text), and it didn't work: no errors, but no events too.

my code of js:

 var app = {
     debug: true,
     log: function(obj) {
         if (this.debug) {
             console.log(obj);
         }
     },
 }; 

 //--------------
 // Models
 //--------------
 app.todo = Backbone.Model.extend({
     defaults: {
         title: '',
         descr: '',
         created_at: Date(),
         completed: false
     }
 });

 //--------------
 // Collections
 //--------------
 app.todoList = Backbone.Collection.extend({
     model: app.todo,
     localStorage: new Store("backbone_todo")
 });



 app.AppView = Backbone.View.extend({
     el: $('body'),
     events: {
         'click .nav_todo_list': 'todo_homepage',
         'click .nav_todo_editor': 'todo_editor',
         'click .nav_todo_constructor': 'todo_constructor',
     },
     todo_homepage: function() {
         app.router.navigate("todo_homepage", true);
     },

     todo_editor: function() {
         app.router.navigate("todo_editor", true);
     },

     todo_constructor: function() {
         app.router.navigate("todo_constructor", true);
     },
 });

 app.ApptodoView = Backbone.View.extend({
    el: $('#todo_constructor'),
    initialize: function () {
        //this.input = this.$('#new_todo_title');
        var new_todo_title = $("#new_todo_title").val();
        var new_todo_descr = $("#new_todo_descr").val();
        var new_todo_status = $("#new_todo_status").val();
      },
      events: {
        'click #new_todo_save_btn': 'createtodoOnClick'
      },
      createtodoOnClick: function(e){
        console.log("createtodoOnClick");
        app.todoList.create(this.newAttributes());
        new_todo_title.val(''); // clean input box
        new_todo_descr.val(''); // clean input box
        new_todo_status.val(''); // clean input box
      },
      newAttributes: function(){
        return {
          title: new_todo_title.trim(),
          descr: new_todo_descr.trim(),
          created_at: Date(),
          completed: new_todo_status.trim()
        }
      }
 });

 //--------------
 // Routers
 //--------------

 app.Router = Backbone.Router.extend({
     routes: {
         "": "todo_homepage", // Пустой hash-тэг
         "todo_editor": "todo_editor", // Блок удачи
         "todo_constructor": "todo_constructor" // Блок ошибки
     },
     todo_homepage: function() {
         $("section").hide(); //
         $("#todo_homepage").show();
     },

     todo_editor: function() {
         $("section").hide();
         $("#todo_editor").show();
     },

     todo_constructor: function() {
         $("section").hide();
         $("#todo_constructor").show();
     }
 });

 //--------------
 // Initializers
 //--------------   


 $(document).ready(function() {
     app.router = new app.Router();
     Backbone.history.start();
     app.todoList = new app.todoList();
     app.appView = new app.AppView();
     app.apptodoView = new app.ApptodoView();
 });

and some part of html:

<body>
    <nav>
        <a href="#/" class="nav_todo_list">todo List</a>
        <a href="#/todo_editor" class="nav_todo_editor">todo Editor</a>
        <a href="#/todo_constructor" class="nav_todo_constructor">todo Constructor</a>      
    </nav>

    <section id="todo_homepage">
        <h1>todo List</h1>
        <section id="main">
            <ul id="todo_list_homepage"></ul>
        </section>
    </section>

    <section id="todo_editor">
        <h1>todo Editor</h1>
        <section id="main">
            <ul id="todo_crud"></ul>
        </section>
    </section>

    <section id="todo_constructor">
            <h1>todo Constructor</h1>
            <label for="todo_title">Title:</label>
            <input id="new_todo_title"">
            <label for="todo_status">Status:</label>
            <select id="new_todo_status" name="todo_status">
                <option selected value="false">Not completed.</option>
            <option value="true">Completed.</option>
       </select>
       <input type="button" id="new_todo_save_btn" value="Save">

    </section>
</body>

also you could check fiddle:

http://bit.ly/1nzsP5a

there - console works, but in my example on localMachine: no - what's the problem? What i do wrong?

(you could run it from my dropbox: http://bit.ly/1tLW2N1)

why events are not fireing? maybe someone could help, becouse spend whole day and didn't find solution

when i wrap whole code in:

$(window).load(function(){});

all is ok, but i think that this is a bad practice. How is it right to do?

Upvotes: 0

Views: 46

Answers (1)

machineghost
machineghost

Reputation: 35822

I see two major issues with the code you provided.

The first problem is that your Views aren't getting their el set. If you try adding a console.log like so:

 app.taskList = new app.TaskList();
 alert(app.taskList.el)

you will see that taskList's el is actually undefined. In general in Backbone you want to define the el when you instantiate the View, not when you define it. In other words, instead of:

app.AppTaskView = Backbone.View.extend({
    el: $('#task_constructor'),

 app.taskList = new app.TaskList();    

try doing:

app.AppTaskView = Backbone.View.extend({

app.taskList = new app.TaskList({el: '#task_constructor');

The second issue I see is that you seem to be misunderstanding how scope works in Javascript. When you define a variable like this:

initialize: function () {
    //this.input = this.$('#new_task_title');
    var new_task_title = $("#new_task_title").val();

it will only be available inside the initialize function. Thus, when you try to use it later:

createTaskOnClick: function(e){
    console.log("createTaskOnClick");
    app.taskList.create(this.newAttributes());
    new_task_title.val(''); // clean input box

it won't work because new_task_title won't exist. You can fix this by making those variables properties of the View instead:

initialize: function () {
    //this.input = this.$('#new_task_title');
    this.new_task_title = $("#new_task_title").val();

createTaskOnClick: function(e){
    console.log("createTaskOnClick");
    app.taskList.create(this.newAttributes());
    this.new_task_title.val(''); // clean input box

Upvotes: 3

Related Questions