Skip to content

Latest commit

 

History

History
311 lines (241 loc) · 9.69 KB

README.md

File metadata and controls

311 lines (241 loc) · 9.69 KB

Travis Status for radify/angular-model Coverage Status Dependency Status devDependency Status Code Climate

Angular Model

Simple HATEOS-oriented persistence module for AngularJS.

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.

Basic Usage

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'
]);

API documentation

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.

Configuration

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

Defaults

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

Creating instances of your model

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

Instance Methods

angular-model instances have instance methods, similar to objects in the OOP world.

Default instance methods

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.

Custom instance methods

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

Class methods

Default class methods

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.

Custom class methods

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']

Collection methods

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.

Default collection methods

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.

Custom collection methods

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
  }
});

Running unit tests

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.

Related

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.