I'm planning on using ember.js, however my REST api doesn't exactly align with the packaged REST Adapter. I would like to "override" find and be able to put my own ajax in it. I dislike how an ember findAll retrieves all my documents with no options for pagination, so that along with other query parameters would be useful --which is why I want to write my own ajax. I've been unable to find any documentation on how I would go about doing this.
In Ember Data, an Adapter determines how data is persisted to a backend data store. Things such as the backend host, URL format and headers used to talk to a REST API can all be configured in an adapter. Ember Data's default Adapter has some built-in assumptions about how a REST API should look.
A Service is an Ember object that lives for the duration of the application, and can be made available in different parts of your application. Services are useful for features that require shared state or persistent connections. Example uses of services might include: User/session authentication. Geolocation.
This is up to date as of Ember Data 1.0 beta 9.
Extend one of the Ember Data Adapters. To make it site wide:
App.ApplicationAdapter = DS.RESTAdapter.extend(....
To make it model specific:
App.FooAdapter = DS.RESTAdapter.extend(...
Then you will define the implementation you'd like to override. You always have the option to call this._super
and revert to the base implementation. e.g.
App.NotesAdapter = DS.RESTAdapter.extend({ find: function(store, type, id) { id = "foo" + id; return this._super(store, type, id); } });
Or you can completely override the implementation:
App.NotesAdapter = DS.RESTAdapter.extend({ find: function(store, type, id) { // Do your thing here return this.ajax(this.buildURL(type.typeKey, id), 'GET'); }, findAll: function(store, type, sinceToken) { // Do your thing here var query; if (sinceToken) { query = { since: sinceToken }; } return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, findQuery: function(store, type, query) { // Do your thing here return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, findMany: function(store, type, ids, owner) { return this.ajax(this.buildURL(type.typeKey), 'GET', { data: { ids: ids } }); }, ..... });
To see the complete api you can override see: http://emberjs.com/api/data/classes/DS.RESTAdapter.html
Often more important will be rolling your own serializer for massaging the data to fit your rest endpoint. Here's some useful information from the transition document https://github.com/emberjs/data/blob/master/TRANSITION.md .
The short version is that once an Ajax request has completed, the resulting payload is sent through the following hooks:
App.PostSerializer = DS.RESTSerializer.extend({ extractSingle: function(store, type, payload, id) { // massage this._super(store, type, payload, id); }, extractArray: function(store, type, payload) { // massage this._super(store, type, payload); }, normalize: function(type, hash, property) { // massage this._super(type, hash, property); } });
App.FooAdapter = Ember.Object.extend({ find: function(id){ return $.getJSON('http://www.foolandia.com/foooo/' + id); } });
Then from your route, or wherever
App.FooRoute = Ember.Route.extend({ model: function(){ var adapter = App.FooAdapter.create(); return adapter.find(1); } });
Now personally I'd inject the adapter onto the routes just to make my life easier:
App.initializer({ name: "fooAdapter", initialize: function (container, application) { application.register("my:manager", application.FooAdapter); application.inject("controller", "fooAdapter", "my:manager"); application.inject("route", "fooAdapter", "my:manager"); } });
Then on the route you could be lazier and do:
App.FooRoute = Ember.Route.extend({ model: function(){ return this.fooAdapter.find(1); } });
Example: http://emberjs.jsbin.com/OxIDiVU/676/edit
You can read more about Ember without Ember Data: Ember without Ember Data
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With