exporting and use the backbone model and view thow error - backbone.js

I am using 'require.js' in my app, i am getting this error :
ReferenceError: Can't find variable: appModel
require.js:32Error: Load timeout for modules: listView
i unable to understand what is wrong with my side:
my config is :
requirejs.config({
baseUrl:"scripts",
paths:{
//libraries
jquery :"lib/jquery-1.9.0.min",
jqueryUI :"lib/jquery-ui-1.9.2.custom.min",
underScore :"lib/lodash-1.0.0.min",
backBone :"lib/backbone-min",
//scripts
appInit :"js/tasklist",
loginValidate :"js/loginValidate",
listModel :"js/models/listModel",
listCollection :"js/collections/listCollection",
listView :"js/views/listView"
},
shim:{
"underScore":{
exports: "_"
},
"backBone":{
exports:"Backbone",
deps:["underScore"]
},
"appInit" : {
deps:["jquery","jqueryUI","underScore","backBone"]
},
"jqueryUI":{
deps:["jquery"]
},
"loginValidate":{
deps:['jquery']
},
"listModel":{
exports:"listModel",
deps:["backBone"]
},
"listCollection":{
exports:"listCollection",
deps:["listModel"]
},
"listView":{
exports:"listView",
deps:["listModel","listCollection"]
}
}
});
require(['jquery'],function(){
if($('#tlLoginForm').length){
require(["jquery","loginValidate"],function($){
$(function(){
var paramsLoginForm = {
loginForm : $('#tlLoginForm')
};
var validate = tasklistHandler(paramsLoginForm);
validate.init(); //it works fine.
});
});
}
if($("#boardTemplate").length){ // i am finding my template and initiating the values
require(["backBone","listModel","listCollection","listView"], function(){
});
};
});
my model in the listModel.js
require(['jquery','backBone'],function($,Backbone){ // i am importing jquery, and backbone and assigning the model
var appModel = Backbone.Model.extend({
url : 'data/data.json',
defaults:{
"id" :"id",
"title" :"Title",
"projectName" :"project",
"dueDays" :0,
"dueTime" :0,
"dueDate" :"0-0-0000",
"totalTasks" :0,
"taskCompleted" :0,
"percent" :65,
"taskStatus" :"Assigned",
"jobtype" :"vip",
"username" :"scott.pierce#groupfmg.com",
"notes" :"notes1"
}
});
return appModel; // tried not works
});
my collection in listCollection.js
define(["jquery","backBone","listModel"],function($,Backbone,model){
// i am importing jquery, backbone, and model i declared in listModel.js, but it's not
work!
console.log('collection',model); // i am getting undefined for model
var collection = Backbone.Collection.extend({
model:model,
initialize:function(){
console.log(this.model);
}
});
var newModel = new appModel; //ReferenceError: Can't find variable: appModel
console.log(newModel); // throw the error as like i mentioned.
});
any one can help me to correct my issue please?

This is works for me..
Instead of using "require" i used "define". it all sets fine now.
thanks all.

Related

Dynamic sort in backbone collection not working

So I have a very basic backbone collection and model. I currently do not have a view as I'm rendering the collection through a custom template. What I'd like to do is sort the collection through an event (clicking on a column header). The event sets a new comparator, and then fires the .sort() method on the collection. However, when I dump the collection data after the .sort(), the collect is in the same order. I'm new to backbone and collections, so perhaps I'm missing something. Here's my code:
var TicketCollection = Backbone.Collection.extend({
model : TicketModel,
initialize : function() {
},
fetch : function(options) {
options = options ? options : {};
var self = this;
$.ajax({
url : "/getTickets",
data : {},
method : "POST",
cache : false,
dataType : "json",
success : function(Json) {
self.reset(Json);
},
complete : options.complete
});
},
render : function() {
var self = this;
Base.renderTemplate({el : $("#ticketListContainer"), Template : "ticketList", data : {tickets : this.toJSON()}});
$("#ticketList").find("#tdHeadCompany").click(function() {
self.comparator = function(ticket) {
ticket.get("company");
};
self.sort();
console.log(JSON.stringify(self.toJSON()));
});
},
comparator : function(ticket) {
return ticket.get("number");
}
});
The console.log shows the collection is still in its original order, and not being ordered by "company" as I'd like when the company header is clicked. Any advice? Thanks!
And I was missing a return in my comparator function. Thanks for pointing that out, Andrew!

Backbone "at()" is returning undefined as result in Firebug

I'm trying to follow a screencast on how to return a result from a database using Backbone.js and REST. My RESTful service (at least I think it's RESTful -- REST is new to me) is serving up JSON data like you would want. Everything appears to work fine until the last step when I try to access the data using at(). Here is my code.
This is my Backbone:
(function() {
window.App = {
Models: {},
Collections: {},
Views: {},
Router: {}
};
window.template = function(id) {
return _.template( $('#' + id).html());
};
var vent = _.extend({}, Backbone.Events);
App.Router = Backbone.Router.extend({
routes: {
'' : 'index',
'*other' : 'other'
},
index: function() {
},
other: function() {
}
});
App.Models.Main = Backbone.Model.extend({
defaults : {
FName: ''
}
});
App.Collections.Mains = Backbone.Collection.extend({
model: App.Models.Main,
url: '../leads/main_contact'
});
new App.Router;
Backbone.history.start();
})();
In the Firebug console, which is what's used in Jeffrey Way's screencast, I type the following:
mains = new App.Collections.Mains();
mains.fetch();
mains.toJSON();
That works fine. I can use Firebug to see that there is the proper data there. Here is my result:
[Object { id="1023", timestamp="2012-05-16 08:09:30", FName="EulĂ lia", more...},...
But when I try to access the object with the id of 1023, I get "undefined." I do this:
mains.at(1023).get('FName');
What am I doing wrong?
the at method retrieves an element at a specific index in the collection.
So if you want to get the element at position 1023, you need 1023 items in your collection. Which you probally don't have.
The id that you have and set to 1023 has nothing to do with index in that collection.

backbone.js getting data into collection and template

i am new to backbone.js and need a little help sending data to a template. Im using a model with fetch, and a collection. here is the code :
(function($) {
var UserModel = Backbone.Model.extend({
urlRoot : '/users',
defaults : {
name : '',
email : ''
},
initialize : function() {
_.bindAll(this);
this.fetch();
},
parse : function(res) {
return JSON.stringify(res);
},
});
var users_coll = Backbone.Collection.extend({
//model: UserModel
initialize : function() {
var u = new UserModel();
this.model = u;
}
});
var displayView = Backbone.View.extend({
initialize : function() {
this.collection = new users_coll();
//_.each(this.collection.models, alert);
//console.log(this.collection);
//alert(JSON.stringify(this.collection.models));
this.render();
},
render : function() {
var tmpl = _.template($("#data-display-tpl").html());
this.$el.html(tmpl);
}
});
var view = new displayView({
el : $("#data-display")
});
})(jQuery);
it's working fine upto the model part. In the parse function of the model, i have used console.log() and everything seems fine. i get a properly formated json, and the fetch works fine too.
however in my collection i get nothing when i try console.log(user_coll.models).
i think i am probably missing something really small. not sure what, maybe the flow of things is all wrong.
I tried to modify your code just a bit to get poin trough...hope it helps clarify few basics.
I also didn't try provided example, but in theory it should work ;)
Here is how his example should be done...
Let's imagine Twitter app for example. Twitter app has only one model that represents one user in system. That's UserModel
var UserModel = Backbone.Model.extend({
urlRoot : '/user', // this is just for modifying one specific user
defaults : {
name : '',
email : ''
},
initialize : function() {
_.bindAll(this);
//this.fetch(); // WRONG: This call was "wrong" here
// fetch() should be done on Collection not model
},
parse : function(res) {
return JSON.stringify(res);
},
});
Now, you can have many lists of users on Twitter right. So you have two lists. In one list you have Friends users, and in other Family users
var UsersFriendsCollection = Backbone.Collection.extend({
model: UserModel // you tell Collection what type ob models it contains
url: '/users/friends',
initialize : function() {
// jabadaba whatever you need here
}
});
var UsersFamilyCollection = Backbone.Collection.extend({
model: UserModel // you tell Collection what type ob models it contains
url: '/users/family',
initialize : function() {
// jabadaba whatever you need here
}
});
...
var displayView = Backbone.View.extend({
initialize : function() {
this.collection = new UsersFriendsCollection();
this.collection.fetch(); // so you call fetch() on Collection, not Model
console.log(this.collection); // this should be populated now
//_.each(this.collection.models, alert);
//alert(JSON.stringify(this.collection.models));
this.render();
},
render : function() {
// collection data is avail. in templating engine for iteration now
var tmpl = _.template($( "#data-display-tpl" ).html(), this.collection);
this.$el.html(tmpl);
}
});
A collection's model attribute is meant for specifying what type of model the collection will contain and if specified you can pass the collection an array of raw objects and it will add and create them. From the docs
Override this property to specify the model class that the collection
contains. If defined, you can pass raw attributes objects (and arrays)
to add, create, and reset, and the attributes will be converted into a
model of the proper type
So when in your code you have
var u = new UserModel();
this.model = u;
You aren't actually adding the model to the collection. Instead you can use the collections add or fetch methods.

Backbone.js fetch unknown error

I'm facing an issue with my backbone.js app: I'm trying to fetch data from a JSON webservice, the GET HTTP request is successfull (i had a look in the developer console of chrome) but backbone fetch trigger an error and doesn't update the model.
You can have a look here to the code:
https://github.com/tdurand/faq-app-client-mobile
And you can run the app and try to debug here:
http://tdurand.github.com/faq-app-client-mobile/
The JSON Feed is like this
[
{
"title":"Probleme ou Bug",
"desc":"Pour les problemes ou les bugs rencontrés",
"entries":[
{
"title":"testdqs",
"desc":"testqsdqs"
}
]
}
]
My collection model is:
var Categories = Backbone.Collection.extend({
url:"http://cryptic-eyrie-7716.herokuapp.com/faq/fr",
model:Category,
parse:function(response) {
console.log("test")
console.log(response);
return response;
},
sync: function(method, model, options) {
var params = _.extend({
type: 'GET',
dataType: 'jsonp',
url: model.url,
processData:false
}, options);
return $.ajax(params);
},
});
And my view:
var IndexView = Backbone.View.extend({
el: '#index',
initialize:function() {
Categories.fetch({
success: function(m,r){
console.log("success");
console.log(r); // => 2 (collection have been populated)
},
error: function(m,r) {
console.log("error");
console.log(r.responseText);
}
});
Categories.on( 'all', this.render, this );
},
//render the content into div of view
render: function(){
//this.el is the root element of Backbone.View. By default, it is a div.
//$el is cached jQuery object for the view's element.
//append the compiled template into view div container
this.$el.html(_.template(indexViewTemplate,{categories:Categories}));
//Trigger jquerymobile rendering
$("#index").trigger('pagecreate');
//return to enable chained calls
return this;
}
});
return IndexView;
Thanks a lot for your help
From what I see, you're not making an instance of your collection anywhere. Javascript isn't really object oriented and it has this weird functions-as-classes and prototype -inheritance type of deal that can confuse anyone coming from the OO -world.
var Categories = Backbone.Collection.extend...
What happens above is that you extend the Backbone Collection's (which is a function) prototype properties with the object (or dictionary) you define. To be able to instantiate this 'class' to an object, you need to use the new keyword. You don't do this, so you are calling the function fetch of the 'class' Categories, which will produce unexpected results.
So instantiate your collection before fetching:
initialize:function() {
this.collection = new Categories(); // instantiate the collection
// also set event handlers before producing events
this.collection.on( 'all', this.render, this );
this.collection.fetch({
success: function(m,r){
console.log("success");
console.log(r); // => 2 (collection have been populated)
},
error: function(m,r) {
console.log("error");
console.log(r.responseText);
}
});
}
Hope this helps!
I found my mistake.
My backend server (with play! framework), was not rendering JSONP properly
This is the code i now use to do it if someone has the same issue.
//Render JSONP
if (request.params._contains("callback")) {
Gson gson = new Gson();
String out = gson.toJson(categoryJSON(categories,lang));
renderText(request.params.get("callback") + "(" + out + ")");
} else {
renderJSON(categoryJSON(categories,lang));
}

Can't get template to display using backbone.js and underscore

I'm really new to Backbone, and I've looked everywhere to try and figure this out. Fundamentally I get how Models, Views, Collections and Templates work together, but for some reason I just can't get my Collection to render in a template. Using Firebug, I get a "this.model is undefined"
Here's my code:
(function($) {
window.Category = Backbone.Model.extend({});
window.Categories = Backbone.Collection.extend({
url: "src/api/index.php/categories?accounts_id=1",
model: Category
});
window.categories = new Categories();
categories.fetch();
window.CategoriesView = Backbone.View.extend({
initialize:function () {
_.bindAll(this,"render");
this.model.bind("reset", this.render);
},
template:_.template($('#tpl-category').html()),
render:function (eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
}
});
var testTargetvar = new CategoriesView({ el: $("#collection") });
})(jQuery) ;
This is the data that my REST service generates:
[
{
"name": "Web Design",
"id": 0
},
{
"name": "Web Development",
"id": 0
},
{
"name": "Waste Management Solutions",
"id": 0
}
]
The "fetch" that I'm using does show the fetched data in Firebug.
And lastly, here's my template:
<div id="collection"></div>
<!-- Templates -->
<script type="text/template" id="tpl-category">
<span><%=name%></span>
</script>
I've verified that all the necessary scripts, jquery, backbone, underscore, etc. are being loaded onto the page properly.
I don't see where you're setting the model property of the view object. Your view constructor also seems to be confused between whether it represents the collection of categories (as suggested by the #collection selector) or a single category (as suggested by the template and use of the model property). Here is a working example that should help guide you to your complete solution:
http://jsfiddle.net/RAF9S/1/
( function ( $ ) {
var Category = Backbone.Model.extend( {} );
var Categories = Backbone.Collection.extend( {
url : "src/api/index.php/categories?accounts_id=1",
model : Category
} );
var categories = new Categories( [
{ name : "One" },
{ name : "Two" },
{ name : "Three" }
] );
var CategoryView = Backbone.View.extend( {
initialize : function () {
_.bindAll( this,"render" );
this.model.bind( "reset", this.render );
},
template : _.template( $( '#tpl-category' ).html() ),
render : function ( eventName ) {
this.$el.empty().append(
$( this.template( this.model.toJSON() ) ).html()
);
if ( ! this.el.parentNode ) {
$( "#collection" ).append( this.el );
}
return this;
}
// render
} );
var view, views = {};
categories.each( function ( category ) {
view = new CategoryView( {
tagName : 'span',
model : category
} );
view.render();
views[ category.id ] = view;
} );
} )( jQuery );
In this case I've simply manually populated the collection with several models in lieu of your fetch method. As you can see, I instantiate a view for each model and pass the model object as the model property.
In the render method I empty the view element (this.el / this.$el), then render the template and append the content of its root element to this.$el. That's so I get the new content without wiping out the element itself. Then, for the purposes of this example, I test whether the element is already in the document, and if not I append it to #container.
I always load my templates in my functions...that might help..
initialize: function(){
_.bindAll(this, 'render');
this.template = _.template($('#frame-template').html());
this.collection.bind('reset', this.render);
},
render: function(){
var $stages,
collection = this.collection;
this.template = _.template($('#frame-template').html());

Resources