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 = []

});