Backbone Collection not using it's model - javascript

I have a simple Model:
App.Models.Client = Backbone.Model.extend({});
And a simple Collection:
App.Collections.Clients = App.Collections.Base.extend({
model: App.Models.Client,
urlRoot: '/clients'
});
The Base collection is simple:
App.Collections.Base = Backbone.Model.extend({
url: function() {
return App.BaseURL + this.urlRoot;
}
});
The problem is, when I do:
var c = new App.Collections.Clients();
c.fetch();
The objects in this collection are Object literals, not of type App.Model.Client
What am I doing wrong?

should it be
App.Collections.Base = Backbone.Collection.extend({
url: function() {
return App.BaseURL + this.urlRoot;
}
});
not Backbone.Model

Related

Model is not a constructor-Backbone

I have created a model and collection for a json to be fetched as shown here.When i'm instantiating in the service i'm getting error that my model is not a constructor.My model uses collection of models for storing time/value pairs.
ServiceMonitoringModel.js
define(function(require) {
'use strict';
var _ = require('underscore');
var Backbone = require('backbone');
var ServiceMonitoringCollection=require('./ServiceMonitoringCollection');
var ServiceMonitoringModel = Backbone.Model.extend({
modelNAme: 'ServiceMonitoringModel',
idAttribute: 'id',
defaults: {
// todo
content_type: '',
content_graph: {
capacity: null,
performance: {
memory: new ServiceMonitoringCollection(),
cpu: new ServiceMonitoringCollection()
}
}
},
initialize: function() {
//todo
},
validate: function(attributes) {
},
parse: function(response) {
return {
content_type: response.content_type,
content_graph: {
capacity:this.getDeepJsonValue(response, 'capacity'),
performance: {
memory: new ServiceMonitoringCollection(this.getDeepJsonValue(response, 'memory'),{parse:true}),
cpu: new ServiceMonitoringCollection(this.getDeepJsonValue(response, 'cpu'),{parse:true})
}
}
};
}
});
return ServiceMonitoringModel;
});
Service.js
...
var ServiceMonitoringModel=require('common/model/server/ServiceMonitoringModel');
var ServiceMonitoringModel = new ServiceMonitoringModel();
Your problem is:
var ServiceMonitoringModel = new ServiceMonitoringModel();
You are assigning a value to your Model definition. Try:
var serviceMonitoringModel = new ServiceMonitoringModel();
Notice the lowercase s

Backbone collection inside model

I'm new to backbone and I wonder if there is a way to save previous models in a collection as an attribute of the model itself. For example,
var history = Backbone.Collection.extend({});
var myModel = Backbone.Model.extend({
defaults: {
id: '',
name: '',
history: history //history is a collection of myModel
},
//override setter so when set method is called, it will save the previous model inside history collection.
})
This would be ephemeral history
var myModel = Backbone.Model.extend({
defaults:{
id:''
},
constructor: function(){
this.history = new Backbone.Collection();
},
set: function(){
var args = Array.prototype.slice.call(arguments);
this.history.add(this.toJSON());
return Backbone.Model.prototype.set.apply(this, args);
}
});

Backbone - Possible to get the collection from a model

I'm wondering if there's a way to get a reference to a collection from one of its models. For instance, if any of the people in the collection below are somehow aware of belonging to a collection, or multiple collections. Fiddle
(function() {
window.App = {
Models: {},
Views: {},
Collections: {}
};
App.Models.Person = Backbone.Model.extend({
defaults: {
name: 'John',
phone: '555-555-5555'
}
});
App.Views.Person = Backbone.View.extend({
tagName: 'li',
template: _.template("<%= name %> -- <%= phone %>"),
render: function(){
var template = this.template( this.model.toJSON() );
this.$el.html( template );
return this;
}
});
App.Collections.People = Backbone.Collection.extend({
model: App.Models.Person
});
App.Views.People = Backbone.View.extend({
tagName: 'ul',
add: function(person){
var personView = new App.Views.Person({ model: person });
this.$el.append( personView.render().el );
return this;
},
render: function() {
this.collection.each(this.add, this);
return this;
}
});
})();
var peeps = [ { name: 'Mary' }, { name: 'David' }, { name: 'Tiffany' } ];
var people = new App.Collections.People(peeps);
var peopleView = new App.Views.People({ collection: people });
peopleView.render().$el.appendTo('body');
Each model has a property called collection. In your fiddle, adding console.log(people.models[0].collection) will print out the collection.
Looking through the source code, it looks like this is what's used to do things like remove a model from a collection when the model's destroy() method is called.
Update: see this updated fiddle which creates three person models and two collections. It prints them to the console. It looks like model.collection only refers to the first collection the person was added to, not the second.

Why are my Backbone Models nested strangely within a Collection, requiring drilling down to access methods/properties?

I've got a Collection and a Model, both using attributes/options to augment them with additional capabilities. Here's the Model (LoadRouteGroup):
return Backbone.Model.extend({
initialize: function () {
console.log(this);
},
fetchf: function () {
console.log("FETCH");
}
});
And the Collection (LoadRouteGroups):
return Backbone.Collection.extend({
constructUrl: function(options) {
if (options.groupingType === "facility") {
// TODO: new endpoint: /api/v1/loadroutes?grouping=facility
this.url = clawConfig.endpoints.webApiRootUrl + "/api/loads/facilities";
}
else {
this.url = clawConfig.endpoints.webApiRootUrl + "/api/v1/loadroutes";
}
},
initialize: function (models, options) {
options || (options = {});
this.constructUrl(options);
console.log(this);
}
});
They're instantiated as such:
var loadRouteGroup = new LoadRouteGroup({
entityType: "facility"
});
// WORKS
loadRouteGroup.fetchf();
// assign groupingType option to collection to denote which URL to use
var loadRouteGroups = new LoadRouteGroups({
model: loadRouteGroup
}, {
groupingType: "facility"
});
var firstGroup = loadRouteGroups.at(0);
// DOESN'T WORK
firstGroup.fetchf();
// WORKS
firstGroup.attributes.model.fetchf();
I would expect that call to firstGroup.fetchf() to work... but it doesn't. Instead, I have to weirdly drill down and use firstGroup.attributes.model.fetchf() in order to access the method.
What's going on here? This would seem straightforward to me, but I can't for the life of me figure out what's wrong with the relationship between my Collection and Model.
The collection definition should include the model type:
return Backbone.Collection.extend({
// ....
model: LoadRouteGroup
});
When initializing the collection, pass in an array of models:
var loadRouteGroup = new LoadRouteGroup({
entityType: "facility"
});
var loadRouteGroups = new LoadRouteGroups([loadRouteGroup], {
groupingType: "facility"
});
Specify the model when you extend the collection instead of when you instantiate.

Backbone.js not saving to database

I am running Django + Backbone.js and .save() has no effect. What am I doing wrong? This is my backbone javascript code. I am trying to implement a prioritized to do list and I cannot figure out how to POST back to the server. Chromium isn't even seeing an attempted post when I try:
T = new Task();
T.save();
In the console.
//$(function() {
/**
* Model: Task
* name, date, importance
*/
window.Task = Backbone.Model.extend({
urlRoot: '/api/v1/task/',
initialize: function() {
console.log("New task: " + JSON.stringify(this.toJSON()));
}
, defaults: function() {
return {
date: new Date()
, name: "New event"
, importance: 0
};
}
});
/**
* Collections: Calendar
*/
window.Calendar = Backbone.Collection.extend({
//urlRoot: '/api/v1/calendar',
initialize: function() {
console.log("New calendar: " + JSON.stringify(this.toJSON()));
}
, model: Task
, comparator: function(task) {
return task.get("date");
}
/*
, before: function(thresholdDate) {
return this.filter( function(task) {
task.get('date') < thresholdDate;
});
}
*/
});
window.TaskView = Backbone.View.extend({
tagName: "li"
});
now = new Date();
Day = Backbone.Collection.extend({
model: Task,
url: '/api/v1/task/?format=json&calendar__id=1&date='+ now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate(),
parse: function(response) {
return response.objects;
},
comparator: function(task){
return task.get('priority');}
});
Month = Backbone.Collection.extend({
model: Task,
url: 'api/v1/task/?format=json&date__month='+(now.getMonth()+1),
parse: function(response){
return response.objects;
},
comparator: function(task){
return task.get('priority');}
});
Year = Backbone.Collection.extend({
model: Task,
url: 'api/v1/task/?format=json&date__year='+now.getFullYear(),
parse: function(response){
return response.objects;
},
comparator: function(task){
return task.get('priority');}
});
// required for saving
Backbone.sync = function(method, model) {
console.log(method + ": " + JSON.stringify(model));
model.id = 1;
};
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
$(function() {
$('form').submit(function() {
var dict = $('form').serializeObject();
var new_task = new Backbone.Model({
date: toString(dict.date),
name: toString(dict.name),
priority: toString(dict.priority)});
console.log("new_task =" + new_task);
new_task.save();
console.log(dict);
return false;
});
});
TaskView = Backbone.View.extend({
el: $("div#app"),
render: function() {
$(thi.el).html(this.template(this.model.toJSON()));
}
});
//});
You have overridden the Backbone.sync method to only log a console message.
If you override Backbone.sync then you need to manually perform the save logic within that method.
So either delete the code where you override Backbone.sync or add the ajax call within that code to perform the save.

Categories

Resources