UNPKG

angular-model

Version:

Simple HATEOS-oriented persistence module for AngularJS.

312 lines (241 loc) 9.93 kB
[![Travis Status for radify/angular-model](https://travis-ci.org/radify/angular-model.svg)](https://travis-ci.org/radify/angular-model) [![Coverage Status](https://coveralls.io/repos/radify/angular-model/badge.svg?branch=master&service=github)](https://coveralls.io/github/radify/angular-model?branch=master) [![Dependency Status](https://david-dm.org/radify/angular-model.svg)](https://david-dm.org/radify/angular-model) [![devDependency Status](https://david-dm.org/radify/angular-model/dev-status.svg)](https://david-dm.org/radify/angular-model#info=devDependencies) [![Code Climate](https://codeclimate.com/github/radify/angular-model/badges/gpa.svg)](https://codeclimate.com/github/radify/angular-model) # 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: ```html // your specific paths may vary <script src="node_modules/radify/angular-model.js"></script> ``` In your app configuration, state a dependency on [Angular Model](https://github.com/radify/angular-model): ```javascript angular.module('myApp', [ 'ur.model' ]); ``` ## API documentation The source code is documented using the ngdoc standard using [gulp-ngdocs](https://www.npmjs.com/package/gulp-ngdocs/). A markdown version is browseable at [/docs](/docs/api.md). To generate documentation in HTML, run: ```bash gulp ngdocs ``` This will output docs into the `build/docs` directory. Then, using a server like `ws`, start a local web server: ```bash 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](/docs/api.md). 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 ```javascript 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: ```javascript 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: ```javascript // 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](/docs/api.md). ### 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. ```javascript 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: ```javascript 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](/docs/api.md). ### Custom class methods angular-model allows you to define class methods on instances. This is similar to static methods in the OOP world. ```javascript 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: ```javascript 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](/docs/api.md). ### Custom collection methods ```javascript 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: ```javascript 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: ```bash npm install ``` You can then run the tests with gulp: ```bash gulp ``` Tests can be found in the `spec` directory of this project. Related -- You may wish to use [Angular Scaffold](https://github.com/radify/angular-scaffold/), which is is a collection of convenience wrappers around angular-model collections. Really helpful for building your AngularJS application with angular-model.