Ember Data is Ember's data-access mechanism. It provides a simple API to deal with data, abstracting the complexities and protocols of data access and diverse data sources. With Ember Data, clients can deal with data models just as any other Ember object.
Ember Data defines a set of fundamental components that handle various roles and responsibilities in data access. These components are grouped under the namespace DS
. The following table describes the most important Ember Data components defined under DS
:
Ember Data components communicate with each other asynchronously for data access operations, based on a promise. The query
and find
methods of both the Store and Adapter are asynchronous, and essentially return a promise object immediately. Once resolved, the model instance is created and returned to the client. The following diagram demonstrates how Ember Data components coordinate a find
method operation asynchronously:
The clients of Ember Data components, which are typically routes, components, controllers, services, and so on, do not directly deal with adapters and serializers. They talk to the Store and model for normal data-access operations. Since the Route.model
method (hook) supports promise objects, the transition will pause until the promise is resolved. We do not deal with resolving promises and hence with asynchronicity; rather, Ember handles it smartly.
Models represent the domain data of an Ember application. They need to be defined in proper structures and registered with the store before they can be used for data access. An Ember CLI project expects models under the app/models/
directory, or app/<pod-dir>/models/
in case you are using the POD directory structure.
Let's see a sample model definition. The following is the definition of a user model:
import DS from 'ember-data'; export default DS.Model.extend({ name: DS.attr('string'), userName: DS.attr('string'), password: DS.attr('string'), dateOfBirth: DS.attr('date'), profileImage: DS.belongsTo('file') });
Model attributes can be of the string, number, Boolean, and date types by default. For custom types, you need to subclass DS.Transform
. Attributes can have default values too. You can specify default values as shown in the following line:
dateOfBirth: DS.attr('date', { defaultValue: new Date() }),
Models can engage in one-to-one, one-to-many, and many-to-many relationships among themselves:
DS.belongsTo
in both model definitionsDS.belongsTo
in one model and DS.hasMany
in the other modelDS.hasMany
defined for each other