Angular Model is a module that provides a simple way to bind client-side domain logic to JSON-based API resources.
By sticking to hypermedia design principles, Angular Model allows you to implement client applications that are cleanly decoupled from your server architecture.
In your AngularJS application, include the JavaScript:
// your specific paths may vary
<script src="node_modules/radify/angular-model.js"></script>
In your app configuration, state a dependency on Angular Model:
angular.module('myApp', [
'ur.model'
]);
The source code is documented using the ngdoc standard using gulp-ngdocs. A markdown version is browseable at /docs.
To generate documentation in HTML, run:
gulp ngdocs
This will output docs into the build/docs
directory. Then, using a server like ws
, start a local web server:
cd build/docs
npm install -g ws
ws
Then, you should be able to browse to http://localhost:8000 to view the API documentation for angular-model.
Here is a quick reference guide to all the configuration settings you can pass to the model() constructor, which is documented in full in the API documentation. Each one is then described in detail later in this document, and in full in the source code in the src
directory.
Setting | Type | Description |
---|---|---|
url | string | API url that this model maps to |
defaults | object literal | Default values of attributes of instances of this model. Similar to properties in OOP. |
$instance | object literal | Instance methods available on each instance of this model. |
$class | object literal | Class methods available on this model. Similar to static methods in OOP. |
$collection | object literal | Collection |
yourApp.config(function(modelProvider) {
modelProvider.model('posts', {
/**
* @ngdoc object
* @name yourApp.posts.defaults
* @description
* Configure the default attributes for instances of posts.
*
* This is similar to an OOP class, which has attributes with defaults, e.g. "public string foo = 'bar';"
*/
defaults: {
name: '', // The name of the post
published: false, // Whether the post has been released to the general public
body: '', // Body text of this post
logo: null, // The logo to show for this post
author: 'John Doe'// Who wrote the post?
}
});
});
Here is an example of how the defaults get used:
var post = model('posts').create({});
console.log(post.author);
=> John Doe
You can use angular-model ad-hoc to construct object instances:
// From defaults
var post = model('posts').create({});
// Specifying fields
var post = model('posts').create({
name: 'some post',
body: "body of some body, it's just some body, you know?",
author: 'Steve Davis'
});
console.log(post.author);
=> Steve Davis
angular-model instances have instance methods, similar to objects in the OOP world.
The following methods are available to every angular-model instance.
Function | Description |
---|---|
$save | Persist an instance to the API |
$delete | Tell the API to delete an instance |
$reload | Refresh an instance of a model from the API |
$revert | Reset the model to the state it was originally in when you first got it from the API |
$exists | Checks whether an object exists in the API, based on whether it has an identity URL. |
$dirty | Returns boolean - true if a model instance has been modified, else false. Opposite of $pristine. |
$pristine | Returns boolean - true if a model instance has unmodified, else false. Opposite of $dirty. |
$related | Hydrates the $links property of the instance. $links are used so that an instance can tell the client which objects are related to it. For example, a post may have an author object related to it. |
$modified | Returns a map of the properties that have been changed |
$hasRelated | Does an instance have a relation of name name ? |
You can see full details of these methods in the API documentation.
angular-model allows you to define instance methods on instances. This is similar to adding methods by extending a base class in the OOP world.
yourApp.config(function(modelProvider) {
modelProvider.model('posts', {
// ...
/**
* @ngdoc object
* @name yourApp.posts.$instance
* @description
* Instance methods that are callable on any individual instance of a post
*/
$instance: {
/**
* @ngdoc function
* @name yourApp.posts.$logo
* @description
* If this post instance has a logo, return it, otherwise return a default string
*
* @return string Either the logo for this post, or a default logo
*/
$logo: function() {
return this.logo || '/logos/default.png';.
}
}
});
});
Example:
var post = model('Posts').create({
logo: 'foo.png'
});
console.log(post.$logo());
=> foo.png
The following methods are available statically to angular-model:
Function | Description |
---|---|
all | Make a request to the API, based on the url configuration setting |
first | Given a query, get the first model instance from the API |
create | Create a new instance of the model. Defaults come from the defaults configuration setting. |
You can see full details of these methods in the API documentation.
angular-model allows you to define class methods on instances. This is similar to static methods in the OOP world.
yourApp.config(function(modelProvider) {
modelProvider.model('posts', {
// ...
/**
* @ngdoc object
* @name yourApp.posts.$class
* @description
* Class methods that are callable on the posts class, or any instance thereof. These
* behave similarly to static methods in OOP languages.
*/
$class: {
/**
* @ngdoc function
* @name yourApp.posts.roles
* @description
* Get an array of valid post types.
*
* @return array The valid types that a post can have. Array of strings
*/
types: function() {
return ['announcement', 'article']
}
}
});
});
Example:
console.log(model('Posts').types());
=> ['announcement', 'article']
You can use collection methods as well, so you can deal with a bunch of instances together. This allows you to have powerful and expressive methods on collections.
The following methods are available statically to angular-model:
Function | Description |
---|---|
add | Saves the object with data |
remove | Find index and delete it from the API, then remove it from the collection |
You can see full details of these methods in the API documentation.
yourApp.config(function(modelProvider) {
modelProvider.model('posts', {
// ...
/**
* @ngdoc object
* @name yourApp.posts.$collection
* @description
* Methods that apply to a collection of posts together
*/
$collection: {
/**
* @ngdoc function
* @name yourApp.posts.$hasArchived
* @description
* Operates on a collection of posts and determines whether any of them are archived
*
* @requires _ Lodash library is used to search the collection
*
* @return string Either the logo for this post, or a default logo
*/
$hasArchived: function() {
return !angular.isUndefined(_.find(this, { archived: true }));
}
}
});
});
Example:
model('Posts').all().then(function(posts) {
if (posts.$hasArchived()) {
// Some of the posts in the collection are archived
}
});
Install the test runner with npm:
npm install
You can then run the tests with gulp:
gulp
Tests can be found in the spec
directory of this project.
You may wish to use Angular Scaffold, which is is a collection of convenience wrappers around angular-model collections. Really helpful for building your AngularJS application with angular-model.