How to construct the url attribute in Backbone.Model and Backbone.Collection? - backbone.js

Currently I'm doing a local Backbone app. And I want to know how to save data, specifically, how to construct the url attribute for Collection and Model. I have created a folder called data which is intended to hold the data. But how is the data structured? Is it just a single json file to hold the whole Collection data in it? Or it has many seprate json files to hold each Model's data individually? If it's a single json file, how should I created the url atrributes for both Collection and Model? If they are many separate json files, What should I do?

It is upto you :) . Backbone.Js models, collections work and can be made to work with pretty much any type of data source that expose through HTTP and URL. But it was designed to work against REST based services out of the box. Since you are interested to test the library and learning it i will advice you to stick to static JSON file or even Twitter timeline service.
Since all collections are in single JSOn file you will need just to set the URl for the collection.
View that renders the collection will instantiate the models and render them from the collection
Application
window["Application"] = {};
Application.Model = {};
Application.Collection = {};
Application.Views = {};
Application.Templates = {};
Application.Router = {};
Collection from url
Application.Collection.TimeLine = Backbone.Collection.extend({
url:"data/collection.json"
});
Current Url is http://localhost/timelineapp/index.html
Collection.Fetch will make GET request to http://localhost/timelineapp/data/collection.json
is this not clear enough i will add more detail

Related

conceptual backbone nested collection

I am using backbone with Node and Express. I have my restful api set up to return my model and collection data. The api works fine. But I'm having trouble binding a route to one of my api paths.
I have a company model and collection so that when go to the routes you get the restful api data for that route:
http://localhost:3000/employees you get the data for restful api path api/employees
http://localhost:3000/employees/1 you get the data for restful api path api/employees/1
I also have a category model and collection to do the same:
http://localhost:3000/categories you get the data for restful api path api/categories
but the following does not work:
http://localhost:3000/categories/Auto you don't get the data for restful api path api/cateogries/Auto The restful api works and returns the right data, but the collection I get in my app returns the same data as the category collection called with the path api/cateogries. Almost like the path gets ignored.
Typically you have a collection and then you provide a id attribute to get a model that belongs to that collection. But what if you want a collection whose id attribute returns another collection? For example, you get a list of categories and then when you select a category you get a list of all the companies in that category? What is the right way to do this in backbone?
Thanks. I actually figured it out. I was returning a collection and needed to adust the url of my collection to point it to the correct path in my restful api. So in my collection I added a url function that goes to a different route if a parameter is passed into the constructor:
url:function(){
if(this.category1){
return "api/categories/"+this.category1;
}
return "api/categories";
},
initialize:function(opts){
this.category1=opts && opts.category1;
}

Adding additional data from server to existing restangular collection

What is the right way to add more data in to an existing collection with Restanglar?
Currently on page load I am performing:
app.factory('Post', ['Restangular', function(Restangular) {
return Restangular.service('posts');
}]);
var Posts = Post.getList({embed:'comments.replies,tags', limit:'50'}).$object;
$scope.posts = Posts;
This gets my initial bunch of posts nicely.
On the front end the user can then select a tag which filters the results, and I want to load up some more from the server for the specific tag. Currently I am replacing the existing posts with:
Posts = Post.getList({embed:'comments.replies,tags', limit:'100', tag:tag.name}).$object;
$scope.posts = Posts;
The data is coming back great from the API. What is the best practice way to push the data in to the exiting/original Restangular collection?
Ideally I want to keep adding to this collection, merging the result so that there are no dupes.
Is there a Restangular method that is used to merge as it seems a common use case. (Could be used for loading additional paginated data too.)

How to synchronize object with children arrays using AngularFire

Hello fellow Angular gurus!
I have a simple website with some galleries. The gallery names and content are saved in Firebase along with few other data.
I would like to synchronize the whole tree with Angular to allow admins to edit anything on the page.
This is how I sync it and it mostly works ...
var ref = new Firebase("https://profile-web.firebaseio.com/");
// create an AngularFire reference to the data
var sync = $firebase(ref);
// download the data into a local object
var syncObject = sync.$asObject();
// synchronize the object with a three-way data binding
syncObject.$bindTo($scope, "data");
... mostly.
What doesn't work is updating data. I think it's because the tree contains objects with arrays as children. AngularFire requires to use $asArray() to work with arrays. It filters out $$hashkey that gets added by Angular's ng-repeat and breaks the update process. $asObject() doesn't do that.
I tried binding the whole tree with $asArray() but since it's not an array it fails.
So my question: How do I sync the whole tree that is an object with arrays as children that have arrays as children themselves?
I have a working copy here
http://tr.tomasreichmann.cz/
Your time and effort is greatly appreciated. Thank you!

Backbone.js: Natively passing attributes to models when fetched with a collection

Let say you are defining a Backbone.js Model. From the documentation we have ...
new Model([attributes], [options])
This seems great for passing some default attributes to a model. When passed the model automatically inherits those attributes and their respective values. Nothing to do. Awesome!
On they other hand lets say we have a Collection of that model.
new Backbone.Collection([models], [options])
Okay, cool we can pass some initial models and some options. But, I have no initial models and no options I need to pass so let's continue. I am going to fetch the models from the server.
collection.fetch([options])
Well I don't have any options, but I want to pass some attributes to add to each models as it is fetched. I could do this by passing them as options and then adding them to the attributes hash in the initialize for the model, but this seems messy.
Is their a Backbone.js native way to do this?
You can pass the attributes as options to fetch and over-ride the collection's parse method to extend the passed options (attributes) on the response.
The solution would look like the following:
var Collection = Backbone.Collection.extend({
url:'someUrl',
parse:function(resp,options) {
if (options.attributesToAdd) {
for (var i=0;i<resp.length;i++)
_.extend(resp[i],options.attributesToAdd);
}
return resp;
}
});
Then to add attributes when you call fetch on the collection, you can:
var collection = new Collection();
collection.fetch({
attributesToAdd:{foo:'bar',more:'foobar'}
});
You may have to tweak the code a bit to work with your JSON structure, but hopefully this will get you started in the correct direction.

Who is supposed fetch a model in a backbone application?

In a backbone application what is the best practice regarding when a model is fetched? I can see the following possibilities.
View calls the model fetch method
Some other JavaScript code calls the fetch model? if so when and what structure would this code have? is this the missing controller concept in Backbone?
A few best practives:
1 Collections and models that are necessary from the very first milliseconds of the app's life should be 'bootstrapped' in place (so there shouldn't be need to fetch them to gain access to vital data)
So when the user is served the correct pages from the server, the models and collections should be already in place (nice example from backbone.js docs)
var ExampleCollection = new Backbone.Collection();
ExampleCollection.reset(<%= #your_collection_data.to_json() %>); // Or whatever your server-side language requires you to do, this is a ruby example
2 The rest can be fetched just in time
The models and collections that aren't needed at the moment your app is initialized can be fetched whenever you feel like it, but I think that the logical time to do that is when the user expresses intent to use those models. E.g. user presses a button to open a view that needs some model/collection -> fetch that collection, user wants to clear unsaved changes from a model -> fetch that model from the server to get the last saved status of the model, and so forth. Usually the place where the fetching is bound to happen is the view that 'owns' the model/collection, because it relays the users actions to the model and displays the model's state to the user.
But like it was said, Backbone.js isn't strict about when a model or collection should be fetched. It can be done anywhere in the app, just make sure you do it only when it's necessary.
Hope this helps!
If you want to be standard, your view must render one time when initialize and listen for the change event of the Model and re render the view every time that model changes, that is all. (regarding what does View needs to do when fetch is completed)
And for call the model.fetch() if you follow the standard that I said, no matters where the fetch is called your view will be updated.
Some people could have a module named load in the view where do something like this:
load : function(){
this.model.fetch();
}
Others could do external fetch call, like this:
var myModel = new YourModel();
var myView = new SomeView( {model : model} );
//Probably you could render with the default data in the while model is fetched
myView.render();
model.fetch();

Resources