1
votes

I am new to backbone underscore and require.js. I followed this tutorial to create a project using backbone.js and underscore.js .

Then I want to add require.js to that project. This is what I modify in the theater.html :

<body>
<h1>My Theater</h1>
<script src="libs/require.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>   

    <div id="mainContainer"></div>

    <input type="button" value="Add Item" id="butAddItem" />

    <script type="text/template" id="tmplt-Movies"> 
        <ul>
        </ul>
    </script>
    <script type="text/template" id="tmplt-Movie">
        <div>*******************************************************</div>
        <div><%= Id %> </div>
        <div><%= Name %> </div>
        <div><%= AverageRating %> </div>
        <div><%= ReleaseYear %> </div>
        <div><%= Url %> </div>
        <div><%= Rating %> </div>
    </script>
</body>  

I added fews line of code to main.js file :

require.config({ 
   paths: { 
     jquery: 'libs/jquery-1.7.1', 
     underscore: 'libs/underscore', 
     backbone: 'libs/backbone' 
} }); 

Then I got 2 errors :

1. ReferenceError: Backbone is not defined , Theater.Models.Movie = Backbone.Model.extend({});

This is main.js file : require.config({ paths: { jquery: 'libs/jquery-1.7.1', underscore: 'libs/underscore', backbone: 'libs/backbone' } });

 var Theater = {
   Models: {},
   Collections: {},
   Views: {},
   Templates:{}
  };


  Theater.Models.Movie = Backbone.Model.extend({});


  Theater.Collections.Movies = Backbone.Collection.extend({
     model: Theater.Models.Movie,
     url: "data/movies.json",
     initialize: function(){
     console.log("Movies initialize");
   }
  });

  Theater.Templates.movies = _.template($("#tmplt-Movies").html());

  Theater.Views.Movies = Backbone.View.extend({
     el: $("#mainContainer"),
     template: Theater.Templates.movies,
     //collection: new Theater.Collections.Movies(), //Not needed

     initialize: function () {
       //_.bindAll(this, "render", "addOne", "addAll");
       this.collection.bind("reset", this.render, this);
       this.collection.bind("add", this.addOne, this);
      },

      render: function () {
        console.log("render");
        console.log(this.collection.length);
        $(this.el).html(this.template());
        this.addAll();
     },

    addAll: function () {
      console.log("addAll");
      this.collection.each(this.addOne);
    },

    addOne: function (model) {
       console.log("addOne");
       view = new Theater.Views.Movie({ model: model });
       $("ul", this.el).append(view.render());
    }

   });


  Theater.Templates.movie = _.template($("#tmplt-Movie").html());
  Theater.Views.Movie = Backbone.View.extend({
  tagName: "li",
  template: Theater.Templates.movie,
  //events: { "click .delete": "test" },

  initialize: function () {
      //_.bindAll(this, 'render', 'test');
      this.model.bind('destroy', this.destroyItem, this);
      this.model.bind('remove', this.removeItem, this);
  },

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

  removeItem: function (model) {
    console.log("Remove - " + model.get("Name"));
    this.remove();
  }
 });


Theater.Router = Backbone.Router.extend({
routes: {
    "": "defaultRoute"  //http://localhost:22257/Theater/theater.htm
},

defaultRoute: function () {
    console.log("defaultRoute");
    Theater.movies = new Theater.Collections.Movies();
    new Theater.Views.Movies({ collection: Theater.movies }); //Add this line
    Theater.movies.fetch();
    console.log(Theater.movies.length);
}
});

var appRouter = new Theater.Router();
Backbone.history.start();

//This is a hack for demonstration  purposes
$("#butAddItem").click(null, function () {
    var movie = new Theater.Models.Movie(
    {
        "Id": "BVP3s",
        "Name": "Lord of the Rings: The Return of the King: Extended Edition: Bonus Material",
        "AverageRating": 4.3,
        "ReleaseYear": 2003,
        "Url": "http://www.netflix.com/Movie/Lord_of_the_Rings_The_Return_of_the_King_Extended_Edition_Bonus_Material/70024204",
        "Rating": "PG-13"
     }
  );

  Theater.movies.add(movie);
  console.log(Theater.movies.length);
});

And i have no idea how to convert the main.js and create a app.js file for using require.js.

Any idea please.

Thank you so much.

1
You can try backbone boilerplate for this that could be a good starting point. github.com/backbone-boilerplate/backbone-boilerplate/wiki/…Ajeet Sinha
Thanks @Ajeet-HoneyDreams for your link, but I really want to configure the project that I post above.Nothing
Most likely the problem is that your main.js does not support asyncronous loading of JavaScript files correctly. But without seeing main.js, one cannot tell.Mikko Ohtamaa
@MikkoOhtamaa : I added main.js dear.Nothing

1 Answers

1
votes

Firstly...

<script src="libs/require.js" type="text/javascript"></script>
<script src="main.js" type="text/javascript"></script>

Could be

<script src="libs/require.js" data-main="main.js" type="text/javascript"></script>

Secondly

require.config({
    baseUrl: '.',
    shim: {
        'backbone': {
            deps: ['underscore'],
            exports: 'Backbone'
        }
    },
    deps: ['backbone','jquery'],
    paths: { 
        jquery: 'libs/jquery-1.7.1', 
        underscore: 'libs/underscore', 
       backbone: 'libs/backbone' 
    }
});

require(['app']);

And finally wrap your app.js in a define.

define(function () {

    Theater.Models.Movie = Backbone.Model.extend({});


    Theater.Collections.Movies = Backbone.Collection.extend({
        model: Theater.Models.Movie,
        url: "data/movies.json",
        initialize: function () {
            console.log("Movies initialize");
        }
    });

    Theater.Templates.movies = _.template($("#tmplt-Movies").html());

    Theater.Views.Movies = Backbone.View.extend({
        el: $("#mainContainer"),
        template: Theater.Templates.movies,
        //collection: new Theater.Collections.Movies(), //Not needed
        initialize: function () {
            //_.bindAll(this, "render", "addOne", "addAll");
            this.collection.bind("reset", this.render, this);
            this.collection.bind("add", this.addOne, this);
        },

        render: function () {
            console.log("render");
            console.log(this.collection.length);
            $(this.el).html(this.template());
            this.addAll();
        },

        addAll: function () {
            console.log("addAll");
            this.collection.each(this.addOne);
        },

        addOne: function (model) {
            console.log("addOne");
            view = new Theater.Views.Movie({
                model: model
            });
            $("ul", this.el).append(view.render());
        }

    });


    Theater.Templates.movie = _.template($("#tmplt-Movie").html());
    Theater.Views.Movie = Backbone.View.extend({
        tagName: "li",
        template: Theater.Templates.movie,
        //events: { "click .delete": "test" },
        initialize: function () {
            //_.bindAll(this, 'render', 'test');
            this.model.bind('destroy', this.destroyItem, this);
            this.model.bind('remove', this.removeItem, this);
        },

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

        removeItem: function (model) {
            console.log("Remove - " + model.get("Name"));
            this.remove();
        }
    });


    Theater.Router = Backbone.Router.extend({
        routes: {
            "": "defaultRoute" //http://localhost:22257/Theater/theater.htm
        },

        defaultRoute: function () {
            console.log("defaultRoute");
            Theater.movies = new Theater.Collections.Movies();
            new Theater.Views.Movies({
                collection: Theater.movies
            }); //Add this line
            Theater.movies.fetch();
            console.log(Theater.movies.length);
        }
    });

    var appRouter = new Theater.Router();
    Backbone.history.start();

    //This is a hack for demonstration  purposes
    $("#butAddItem").click(null, function () {
        var movie = new Theater.Models.Movie({
            "Id": "BVP3s",
            "Name": "Lord of the Rings: The Return of the King: Extended Edition: Bonus Material",
            "AverageRating": 4.3,
            "ReleaseYear": 2003,
            "Url": "http://www.netflix.com/Movie/Lord_of_the_Rings_The_Return_of_the_King_Extended_Edition_Bonus_Material/70024204",
            "Rating": "PG-13"
        });

        Theater.movies.add(movie);
        console.log(Theater.movies.length);
    });

});

You could switch out your version of backbone for backbone-amd which is a AMD compatible version available through Bower, and use Lodash instead of Underscore. On top of that, you should start thinking about abstracting your backbone models, collections, views and router into separate files.

Hope this helps.