Skip to content

Commit

Permalink
Adds documentation
Browse files Browse the repository at this point in the history
* New gulp task `gulp ngdocs` to generate documentation into build/docs
* Add ngdoc-compliant documentation to source code
* Add documentation to README.md
* Add Markdown version docs in /docs directory
  • Loading branch information
Gavin Davies committed Nov 19, 2015
1 parent 0736db8 commit 1efa96b
Show file tree
Hide file tree
Showing 7 changed files with 1,613 additions and 13 deletions.
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,3 +1,4 @@
.DS_Store
coverage/
node_modules/
node_modules/
build/
15 changes: 12 additions & 3 deletions .jscsrc
@@ -1,5 +1,14 @@
{
"preset" : "google",
"maximumLineLength" : 120,
"disallowMultipleVarDecl" : false
"preset": "google",
"maximumLineLength": 120,
"disallowMultipleVarDecl": false,
"jsDoc": {
"checkAnnotations": {
"preset": "jsdoc3",
"extra": {
"ngdoc": "some",
"methodOf": "some"
}
}
}
}
13 changes: 12 additions & 1 deletion Gulpfile.js
Expand Up @@ -7,7 +7,7 @@ var jshint = require('gulp-jshint');
var jscs = require('gulp-jscs');
var nsp = require('gulp-nsp');
var runSequence = require('run-sequence');
var istanbul = require('gulp-istanbul');
var istanbul = require('gulp-istanbul');

/*
* PLEASE NOTE: run-sequence is a
Expand All @@ -21,6 +21,17 @@ var paths = {
'src': 'src/**/*.js'
};

gulp.task('ngdocs', [], function () {
var gulpDocs = require('gulp-ngdocs');
return gulp.src(paths.src)
.pipe(gulpDocs.process({
html5Mode: false,
startPage: '/api',
title: 'angular-model'
}))
.pipe(gulp.dest('./build/docs'));
});

gulp.task('test', function(done) {
new Server({
configFile: __dirname + '/config/karma.conf.js',
Expand Down
298 changes: 298 additions & 0 deletions README.md
Expand Up @@ -11,3 +11,301 @@
**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.

0 comments on commit 1efa96b

Please sign in to comment.