API - swimlane/angular-model-factory GitHub Wiki
A advanced definition that demonstrates all scenarios.
var module = angular.module('services.zoo', ['modelFactory']);
module.config(function($modelFactoryProvider}{
$modelFactoryProvider.defaultOptions.prefix = 'api';
});
module.factory('AnimalModel', function($modelFactory){
// url will be: `api/zoo` since we added the prefix
var model = $modelFactory('zoo', {
// the default primary key
pk: 'id',
map: {
'zooId': 'id',
// has many
'animals': AnimalModel.List,
// has one
'location': LocationModel
},
// only called on empty inits
defaults: {
'created': new Date()
},
// All return $promise
// Note: All default options are transposed to all new instance
// unless explicitly overridened
actions:{
'base': {
// any $http argument
// before ajax call
// this only manipulates data sent not core object
beforeRequest: function() { /*...*/ },
// after ajax call response
// happens before the object is wrapped
afterRequest: function(){ /*...*/ }
},
// these are implied by default given
// the base url unless overridden like below
// - get
// - query
// - post
// - update
// - delete
'query': {
// lets cache all query requests
// this uses the out of the box angular caching
// for $http. I create a cache factory on each
// instance so you can access it via `$cache` attribute
cache: true
},
// custom methods
'queryFood':{
method: 'GET',
// urls inherit the base url
// url becomes: api/zoo/food
url: 'food',
// doesn't attach prototype methods
wrap: false
},
'update': {
// by default, save/update/delete will all
// invalidate the cache if defined.
invalidateCache: true
},
// anything with $ prefix is attached to instance
'$copy': {
method: 'POST',
url: 'stlouis/zoo/copy',
// overrides the root url
override: true
}
},
list: {
// example list helper
nameById: function(id) {
var user = this.find(function(u){
return u.id === id;
});
return user ? user.name() : "Unavailable";
}
},
instance: {
// instance api
// - $save
// - $destroy
// revision api
// - $diff
// - $commit
// - $rollback
// - $update
// example custom helper
'getName': function(val){
return val.first + ' ' val.last
}
},
// any method that does not represent a http action
// that will be attached to the static class
myStaticMethod: function(){
}
});
return model;
});
Provider
You can use the provider pattern to set default options like:
var module = angular.module('services.zoo', ['modelFactory']);
module.config(function($modelFactoryProvider){
// all models will now strip trailing slashes
$modelFactoryProvider.defaultOptions.stripTrailingSlashes = false;
// all models will now be prefixed by 'api'
$modelFactoryProvider.defaultOptions.prefix = 'api';
});
return module;
Example Usages
Controller
module.controller('ZooCtrl', function ($scope, AnimalModel) {
// create single
var animal = new AnimalModel({
name: 'Panda'
});
// creates if no id
// updates if has id
animal.$save();
// create list
// objects will automatically be wrapped
var animalList = new AnimalModel.List([ {}, {}, ... ]);
// add the model to this list
animalList.push(animal)
// deletes the model
// and removes from the list i pushed into
animal.$destroy();
});
Requests
//-> api/zoo/345234
return AnimalsModel.get(id);
//-> api/zoo/345234?type=panda
return AnimalsModel.get(id, { type: panda });
//-> api/zoo/345234
return AnimalsModel.get({ id: id });
//-> api/zoo?name=panda
return AnimalsModel.query({ name: 'panda' });
UI-Router
$stateProvider.state('zoo', {
url: '/zoo',
templateUrl: 'zoo.tpl.html',
controller: 'ZooCtrl',
resolve: {
animals: function (AnimalsModel) {
return AnimalsModel.query({ name: 'panda' });
}
}
});
Lists
module.controller('ZooCtrl', function ($scope, AnimalModel, animals) {
// animals === [ AnimalModel({ type: 'panda' }) ]
var animal = animals[0];
//-> animals = [ { type: 'panda' } ]
// Update an instance in the list
animal.type = 'lion';
//-> animal[0].type == 'lion'
//-> commits THIS model to server
animal.$save();
// automatically deletes from list
animal.$destroy();
//-> animals = []
});