How to get an url with collection and model ids - javascript

I made a website to create some maps. So, all my maps have an id, and my map has some elements with ids.
So I create a collection Map with an id and its model is my map object :
app.collections.mapDetailsCollection = Backbone.Collection.extend({
model: app.models.mapDetailsModel,
initialize: function(options) {
this.id = options.id;
},
url: function () {
return this.absURL + '/api/maps/' + this.id;
},
parse: function(response){
return response.features;
},
toGeoJSON: function(){
var features = [];
this.models.forEach(function(model){
var feature = model.toGeoJSON();
if (! _.isEmpty(feature.geometry)) {
features.push(feature);
}
});
return {
'type': 'FeatureCollection',
'features': features
};
}
});
But my model have an id too. I don't know for a model how to return url with a collection id.
I need to return /api/maps/id_collection/id_model.

When a model is added to a collection, it receives a reference to the collection. So each model has a collection property this.collection set if it's in a collection.
From the Backbone model constructor documentation (emphasis mine):
If you pass a {collection: ...} as the options, the model gains a
collection property that will be used to indicate which collection the
model belongs to, and is used to help compute the model's url. The
model.collection property is normally created automatically when you
first add a model to a collection. Note that the reverse is not true,
as passing this option to the constructor will not automatically add
the model to the collection. Useful, sometimes.
Then, you could use that to build the full url of a model:
var app.models.mapDetailsModel = Backbone.Model.extend({
urlRoot: function() {
// Backbone adds the model id automatically
return this.collection.url() + '/my-model/';
}
// ...snip...
});
Note that the default url for a model is what you want.
Generates URLs of the form: [collection.url]/[id] by default, but
you may override by specifying an explicit urlRoot if the model's
collection shouldn't be taken into account.

Related

How to extract a specific model from collection,and set id model

Goodmorning,i'm a bit confused about a specific id that a model has got and the id that it's has in parse.com because my collection is linked to parse.com.
If i want to get a specific model from my collection how can i do?
An example,my collection is this:
var Proposte = Backbone.Collection.extend({
model:Proposta,
url:'https://api.parse.com/1/classes/Proposte',
});
return Proposte;
and my model is this:
var Proposta = Backbone.Model.extend({
url:"https://api.parse.com/1/classes/Proposte",
...
If i want to get a specific model from my collection how can i do?
have a try at this:
var item = Proposte.findWhere({'url':"https://api.parse.com/1/classes/Proposte"});
hare is the doc
Edit:
The code above gives you the first matched model of the collection.
If you want to get multiple models that matches the specific attributes of a model, just use where
General case:
Define idAttribute for your Model/Collection:
var Proposta = Backbone.Model.extend({
idAttribute: 'name',
});
var Proposte = Backbone.Collection.extend({
model:Proposta,
url:'https://api.parse.com/1/classes/Proposte'
});
// Done here with static data just for illustration
var collection = new Proposte([{name: 'aaa'}, {name: 'bbb'}]);
Use the defined attribute to retrieve Models from collection:
console.log(collection.get('aaa'));
JSFIddle
URL, of course, can also be that attribute (just in case):
var Proposta = Backbone.Model.extend({
idAttribute: 'url'
});
var Proposte = Backbone.Collection.extend({
model:Proposta,
url:'https://api.parse.com/1/classes/Proposte',
});
var collection = new Proposte([{url: 'https://api.parse.com/1/classes/Proposte/1'}, {url: 'https://api.parse.com/1/classes/Proposte/2'}]);
console.log(collection.get('https://api.parse.com/1/classes/Proposte/2'));

Backbone 101 - Using JSON data with backbone

I'm in the beginning stages of moving my application to the backbone framework.
I have some data that comes in as json from an ajax call
{f1:"f1_value", f2:"f2_value", f3:"f3_value"},
{f1:"f1_value", f2:"f2_value", f3:"f3_value"},
{f1:"f1_value", f2:"f2_value", f3:"f3_value"},
This data set always has 3 columns but may be as long as needed for each set as far as rows goes.
It is used to populate a div after processing it client side into HTML, which correlatively may extend down as far as needed. I was planning on this data chunk representing one view in the framework.
<div id = "data_hold"></div>
How do I match this up to the framework:
var ModelTest,
CollectionTest,
ViewTest;
ModelTest = Backbone.Model.extend({
});
CollectionTest = Backbone.Collection.extend({
model: ModelTest
}
ViewTest = Backbone.View.extend({
});
Backbone 101:
var ModelTest,
CollectionTest,
ViewTest;
ModelTest = Backbone.Model.extend({ });
// associate your collection with a URL. This is static here; it can be
// passed in as an option using the Collection's initialize function()
// instead.
CollectionTest = Backbone.Collection.extend({
model: ModelTest,
url: 'http://localhost/my_json_source'
});
ViewTest = Backbone.View.extend({
// Have a target to render into. This can be an existing element, as
// here, or it can be dynamically generated and attached to the DOM
// programattically.
el: $('#data_hold'),
// specify than when the collection is updated, call the local render
// method.
initialize: function(options) {
this.collection.bind('reset', _.bind(this.render, this));
},
// Empty the element, then append subsequent rows of the collection
// to it as paragraphs. The '_this = this' idiom allows us to access
// the outside context (the View's context), since the each() call
// will create a new inner context.
render: function() {
var _this = this;
this.$el.html('');
this.collection.each(function(l) {
_this.$el.append('<p>' + l.get('f2') + '</p>');
});
}
});
// initialize the collection and view, then fetch the collection, which
// will trigger the render after the collection has been updated.
$(function() {
ct = new CollectionTest();
vt = new ViewTest({collection: ct});
ct.fetch();
});

Calling Backbone.Model.Save converts child-Backbone.Model to object?

I'm creating a Backbone Model which has a child Backbone Model inside of it:
console.log("inside add item, video:", video instanceof Backbone.Model);
var playlistItem = new PlaylistItem({
video: video,
title: video.get('title')
});
afterwards, I save it:
playlistItem.save({}, {
success: function() {
console.log("Successfully saved.");
playlistItem.get('video').get('title');
}
});
In this example, I encounter an error -- video is not an instanceof Backbone.Model after calling save. Why?
I think you will need to override parse and toJSON.
toJSON: function() {
var json = Backbone.Model.prototype.toJSON.call(this);
// replace backbone model with json.
json.video = this.get('video').toJSON();
return json;
},
parse: function(data) {
// take json of video and set into model.
this.get('video').set(data.video);
delete data.video;
return data;
},
If you don't parse the json data like this, backbone is going to take the 'video' object from the json and overwrite your Backbone model.

Having different models for request and response - backbone.js

//A backbone model
var RequestModel = Backbone.Model.extend({});
//A backbone model
var ResponseModel = Backbone.Model.extend({});
RequestModel.save({
success: function (ResponseModel ) {
alert(ResponseModel .toJSON());
}
})
Can i have a separate Model for Request and Response, as both Request and Response does not match. Its a total RPC call and not a CRUD operation.
I've thought about this same problem before, and I feel there isn't a great way to achieve this in Backbone. The best I've come up with is to implement a fromResponse and toRequest method on the model, and override model.parse and model.sync to map the model object to them. Something like:
var Model = Backbone.Model.extend({
fromResponse: function(responseAttrs) {
var modelAttrs = {}; //map response attributes to modelAttrs
return modelAttrs;
},
toRequest: function() {
//map model attributes to response attributes here
var modelAttrs = this.toJSON();
var responseAttrs = {}; //map models attributes to requestAttrs
return responseAttrs;
},
parse: function(response) {
return this.fromResponse(response);
},
sync: function(method, model, options) {
options = options || {};
options.data = this.toRequest();
Backbone.sync(method, model, options);
}
});
If the parse and sync are overridden in some kind of a base class, then you only need to implement the fromResponse and toRequest mappers for each model.
Another option would be to override Backbone.sync altogether, and map each Model type to some kind of ModelRequestMapper and ModelResponseMapper object to (de-)serialize each model. I feel that would be more complicated, but might scale better, if you have lots of models.
/Code sample not tested

Backbone: filtering models from an array of names

Have an array of id's
['tom','tim','joe','matt','scott']
Each model has an attribute that has an id.
How can I grab all 5 of the models and put in a new collection?
How about using the underscore filter method on the corresponding collection?
var ids = ['tom','tim','joe','matt','scott'];
var matches = collection.filter(function (model) {
return ids.indexOf(model.id) > -1;
});
If you need to fetch the models from your persistence layer, you might consider generating a collection of models with the id attribute set and providing an appropriate endpoint to populate the other attributes:
var MyCollection = Backbone.Collection.extend({
model: MyModel, // whatever your model is
url: '/byname' // whatever the endpoint is
});
var models = [];
_.each(ids, function (id) {
models.push({ id: id });
});
var collection = new MyCollection;
collection.fetch({ models: models }); // fetch the associated models
Whatever endpoint you provide (/byname in the example above) should be prepared to generate a collection containing each model whose id was specified in the models parameter.

Categories

Resources