I'm using django+tastypie+backbone.js with backbone-relational.
Let's say i have model(coffee script):
class Track extends Backbone.RelationalModel
And somehow i get the first object's URI:
api/track/1
Result in JSON have to be something like:
{
'title': 'Mytrack',
'length': '120'
}
How can i get full model JSON with all attributes using this URI?
You need to set the model's urlRoot (/api/track), then create a new model with the id you want (1), and call .fetch on the model. The fetch call will be asynchronous, so you need to wait for the success callback before you can access the full properties:
class Track extends Backbone.RelationalModel
urlRoot:"/api/track"
track = new Track id:1
track.fetch
success:(model) -> console.log model
Related
I have the following function, which fails when called:
getAll: function() {
return _todos.toJSON();
}
_todos.toJSON is not a function it tells me.
Printing _todos gives me a function for some reason function child().
Why is that the case?
Here's my Backbone.Model:
var _todos = Backbone.Model.extend();
The getAll() function is sitting in my Collection:
var TodoCollection = Backbone.Collection.extend({
model: _todos,
getAll: ...
});
Edit:
I'm actually connecting Backbone with React, so that might change how I do this.
In addition to getAll I have this:
areAllComplete: function() {
return _.every(this.pluck('complete'), true);
}
An example I've been following seems to put getAll and areAllComplete in the Model and doesn't use Collection at all. I couldn't make sense of it, and since I want this to be restful down the road, I added the Collection and moved getAll and other one inside of it.
Perhaps, this is not what I want.
Edit 2:
According to a warning, the output of getAll is expected to be an Object not an array. I should probably add those function to Model not Collection. Need to think about this more.
I think this turned into another question...
The collection model property is used to specify what model class the collection contains and is used to create the proper models when you pass the raw data to your collection. Additionally based on your code if it did work you would have had a collection with just one model.
Aside from that in order to get the JSON of all the models in your collection you can call it's toJSON method
for example todoCollection.toJSON();
Or if you specifically want it in a getAll function (maybe you want to do something else before returning the data) you can do the following
var TodoCollection = Backbone.Collection.extend({
model: Todo,
getAll: function () {
//do something
return this.toJSON();
}
});
//here we are passing in the data directly, but you might get it with a fetch call
var todoStore = new TodoCollection(models);
var todosJson = todoStore.getAll();
Another thing to note is the backbone naming convention is to use PascalCase for classes and camelCase for instances .
That's because Backbone.Model.extend returns a constructor function. When you pass it to a collection via the model property you're just letting the collection know which kind of models it should hold.
To get the JSON for an entire collection, call toJSON() on the collection instance.
var collection = new TodosCollection();
// add models
collection.toJSON();
If you want JSON for one specific model then get a reference to it via the collection API (at, findWhere, get etc) and call toJSON() on that reference.
var model = collection.at(0);
model.toJSON();
When i am creating the model by extending "Ext.data.Model" class, getter/setter methods are behaving differently than default .get and .set methods available from data.Model
It seems like one can either use getter/setter methods or .get/.set methods, because they seem to be maintaining separate set of fields.
Why is it so? Parden me if question looks silly, i am learning Ext JS an trying to understand how it works. I am using library version ExtJS4.2.1
Class
Ext.define("Ext.model.Invoice", {
extend : "Ext.data.Model",
fields : [{name : 'id'}, {name : 'taxId'}, {name : 'name'}],
config : {
name : 'Tejas',
taxId : '23746'
},
constructor : function(config) {
this.callParent(arguments);
this.initConfig(config);
}
});
HTML
Ext.onReady(function() {
var invoice = Ext.create("Ext.model.Invoice");
console.log("Before, invoice.get('name'):", invoice.get('name'));
console.log("Before, invoice.getName():", invoice.getName());
//Modifying name
invoice.setName("Mr. Smith");
invoice.set("name","Mr. Tony");
console.log("Updating names using setName and set('name')");
console.log("After, invoice.get('name'):", invoice.get('name'));
console.log("After, invoice.getName():", invoice.getName());
});
OUTPUT
Before, invoice.get('name'):
Before, invoice.getName(): Tejas
Updating names using setName and set('name')
After, invoice.get('name'): Mr. Tony
After, invoice.getName(): Mr. Smith
With config configuration property you are defining list of configuration options with their default values, but not default model data.
When instance of object is creating, for each property defined in config is automatically created setter and getter method, and object property with same name as config property.
Ext.data.Model stores model data in its private data property. For example you can try to dump model data for name field by:
console.log(invoice.data.name);
So by setter and getter you access object property, but by model.get() and model.set() you access model's data stored in model's private data property.
Context
I have the following data structure:
class Birthday(ndb.Model):
day = ndb.IntegerProperty()
month = ndb.IntegerProperty()
year = ndb.IntegerProperty()
class User(ndb.Model):
name = ndb.StringProperty()
birthday = ndb.StructuredProperty(Birthday)
# ... other properties
Problem
When I try to use the populate() method on an instance of User, it gives an error: expecting a Birthday instance instead of a dictionary of params.
If I remove the birthday property, everything works fine: the User instance is populated with the dictionary of params.
Shouldn't the populate() method recognize structured properties and automatically populate them as well?
Any clues?
Thanks
PS: The populate method could also use a forgiving mode on which it ignores unknown properties for which there are references on the params dictionary.
>>Added comments
I'm using a generic REST Handler which is extended for accessing and changing several data types. The extension has to define a method getModel() that returns the model class to access/manipulate. The model class has to implement a few methods, namely create(cls, params).
The POST handler parses params (sent by AngularJS using $resouce -- link below) the following way:
# inside the generic REST Handler
params = json.loads(self.request.body, object_hook=self.datetime_decoder) # parse json params
...
self.getModel().create(params) # invokes the create method of the
The model class implements the create method the following way:
#classmethod
def create(cls, params = None):
obj = cls()
if params:
obj.update(**params)
obj.put()
return True, obj
return False, None
The contents of the JSON dict are:
{"name":"Ana Matos","email":"ana.matos#nvd.com","phone":"+35196983465671","birthday":{"day":1,"month":0,"year":1980},"gender":"FEMALE","groups":["2012/2013"],"serviceProviderId":206133}
JSON contens -- firefox screenshot
AngularJS $resource
Are you reporting a bug or requesting a feature? The populate() method requires its parameter types to match the declared type of the property, which in this case is a Birthday instance.
It would help if you showed the contents of the JSON dict that you are passing to populate() (and exactly how you are passing it).
Possibly the solution is as simple as getting the 'birthday' value from the JSON dict and using it to create a Birthday instance. But I would have to see your code to know for sure.
Code:
class Session extends Backbone.Model
initialize: ->
#bind 'change', #save
console.log 'init'
class SessionList extends Backbone.Collection
model: Session
localStorage: new Store 'sessions'
sessions = new SessionList
a = new Session x: 'test'
sessions.add a
console.log a.get 'x'
a.set x: 'new'
console.log a.get 'x'
When loaded in a page with Backbone.localstorage, the console gives:
init
test
Uncaught TypeError: Cannot read property 'localStorage' of undefined
backbone-localstorage.js:70
Backbone.sync
_.extend.save
backbone-localstorage.js:70
Backbone.Events.trigger
backbone.js:304
_.extend.change
backbone.js:117
And when I comment out the #bind call, I get the expected:
init
test
new
I can also save manually successfully after a has been added to sessions with a call to a.save().
I guess the problem is that the Session constructor triggers the change event, and save() doesn't know what to do before a has been added to sessions? So I could instead do something like this:
class Session extends Backbone.Model
set: (fields, ops) ->
super fields, ops
if (this has been added to a Collection)
#save()
Is this the best way to do it? If yes, how do I fill in the if statement?
My suggestion would be to just call save instead of set. so replace this:
a.set x: 'new'
with
a.save x: 'new'
hope that works for you
i have a partial view with a gridview in it. so when user clicks add button request will redirect to Add method of unitsController. After add it to database I should refetch all data from database. Is there a way to prevent controller from get all database records?
Below is my current controller
public class UnitsController : Controller
{
TList<Units> model=null;
public ActionResult UnitsPartial()
{
if(model==null)
model = database.GetAll();
return PartialView(model);
}
[HttpPost]
public ActionResult Add(Units unit)
{
if (ModelState.IsValid)
{
database.Save(unit);
model.Add(unit);
}
return PartialView("UnitsPartial", model);
}
In the last line I want to use return PartialView("UnitsPartial", model) instead of return database.GetAll() to prevent a database query. But model is null in Add method.
Is my approach correct or not? And why is model is null in add() method?
--UPDATED
first of all control redirect to UnitsPartial() and will fill model object correctly. after press add button, control will redirect to Add(...) method but this time model is equal to null !!!
what is the problem with it? i tried to pass model.Clone() to partial view
return PartialView("UnitsPartial", model.Clone());
but the result is the same
You can't cache values in the controller class like this using member variables. HTTP is stateless and MVC 3 follows that approach. Each individual call to an action method is going to have a brand new instance of Controller class with the model set to null.
So start by calling database.GetAll() in both action methods and then ask the question "How do I make this more efficient".
I don't know if it is the right approach or not, since I do not fully understand what you try to do, but your model is null because you initialize it as null when the controller is created. you should do a model = new TList() before adding something to it....