Skip to content

Data Model Example Template

Jonathan Samples edited this page Oct 16, 2015 · 1 revision

Data Model Example Template

Lots of the class below is boilerplate... just copy it. I'll make the boilerplate with comments. Anything denoted with <SOMETHING_HERE> should be considered a placeholder for your class.

/**
 * <CLASS_MODULE_NAME> This should be any unique string that identifies this angular module.  This will
 * be used in the model module.
 */
angular.module('<CLASS_MODULE_NAME>',
    /**
     * <SUPER_CLASS_MODULE_NAME> - If this class is a subclass then put the super class module name
     * in the array below. If it is not a subclass then leave the array empty.
     */
    ['<SUPER_CLASS_MODULE_NAME'],
    function($provide) {
        /**
         * <SHORT_CLASS_NAME> The short name for your class e.g. User (exclude the package).
         * <SUPER_CLASS_NAME> The short name of the class that this class inherits from. If this class
         *                    is not a subclass use 'Class'.
         */
        $provide.factory('<SHORT_CLASS_NAME>',
            function($log, <SUPER_CLASS_NAME>)
            {
                var <SHORT_CLASS_NAME> = <SUPER_CLASS_NAME>.extend
                ({
                    construct: function(){
                        var self = this;

                        var ID;
                        var isProxy = true;
                        var isShell = true;
                        var isValid = true;
                        var isLoading = false;
                        /**
                         * <FULL_CLASS_NAME> e.g. com.something.model.User
                         */
                        var cn = "<FULL_CLASS_NAME>";

                        /**
                         * List all of the class properties here. This includes all primitive properties
                         * and relationships.
                         */
                        var <PROPERTY_NAME>;

                        /*****************************************************
                         * Boiler plate start
                         */
                        Object.defineProperty(this, "isProxy", {
                            get: function() {
                                return isProxy;
                            },
                            set: function(val) {
                                isProxy = val;
                            },
                            enumerable: false
                        });

                        Object.defineProperty(this, "isShell", {
                            get: function() {
                                return isShell;
                            },
                            set: function(val) {
                                isShell = val;
                            },
                            enumerable: false
                        });

                        Object.defineProperty(this, "isValid", {
                            get: function() {
                                return isValid;
                            },
                            set: function(val) {
                                isValid = val;
                            },
                            enumerable: false
                        });

                        Object.defineProperty(this, "isLoading", {
                            get: function() {
                                return isLoading;
                            },
                            set: function(val) {
                                isLoading = val;
                            },
                            enumerable: false
                        });

                        Object.defineProperty(this, "ID", {
                            get: function() {
                                return ID;
                            },
                            set: function(val) {
                                ID = val;
                            },
                            enumerable: true
                        });

                        Object.defineProperty(this, "cn", {
                            get: function() {
                                return cn;
                            },
                            set: function(val) {
                                cn = val;
                            },
                            enumerable: true
                        });
                        /*
                         * Boilerplate end
                         ************************************************/

                        /**
                         * Define all primitive properties like the following 
                         * <PROPERTY_NAME> - the name of your property
                         */
                        Object.defineProperty(this, "<PROPERTY_NAME>", {
                            get: function() {
                                if(this.ID)
                                    this.doLoad();
                                return <;
                            },
                            set: function(val) {
                                color = val;
                            },
                            enumerable: true
                        });

                        /** 
                         * Target Relationships
                         * where the definition (foreign key) is on the other object
                         * Many-to-One or One-to-Ones
                         * <RELATIONSHIP_NAME> - the name of the variable that stores this relationship.
                         */
                        Object.defineProperty(this, "<RELATIONSHIP_NAME>", { 
                            get: function() {
                                this.doLoad();
                                return <RELATIONSHIP_NAME>;
                            },
                            set: function(val) {
                                <RELATIONSHIP_NAME> = val;
                            },
                            enumerable: true
                        });

                        /** 
                         * Source Relationships - where the definition of the relationship (foreign key) is
                         * on this object.
                         * One-to-Many and One-to-One relationships
                         * <RELATIONSHIP_NAME> - the name of the variable that stores this relationship.
                         * <REVERSE_RELATIONSHIP_NAME> - the name of the variable on the other side of the 
                         *                               relationship
                         **/
                        Object.defineProperty(this, "<RELATIONSHIP_NAME>", {  
                            get: function() {
                                this.doLoad();
                                return <RELATIONSHIP_NAME>;
                            },
                            set: function(val) {
                                if (!this.isProxy) {
                                    if (val != null && !val.isShell) {
                                        var existing = false;
                                        for (var i = 0; i < val.<REVERSE_RELATIONSHIP_NAME>.length; i++) {
                                            var object = val.<REVERSE_RELATIONSHIP_NAME>[i];
                                            if (object === self) {
                                                existing = true;
                                                break;
                                            }
                                        }
                                       if (!existing) val.<REVERSE_RELATIONSHIP_NAME>.push(self);
                                    } else if (field != null) {
                                        for (var i = 0; i < field.<REVERSE_RELATIONSHIP_NAME>.length; i++) {
                                            var object = field.<REVERSE_RELATIONSHIP_NAME>[i];
                                            if (object === self) {
                                                field.<REVERSE_RELATIONSHIP_NAME>.splice(i, 1);
                                            }
                                        }
                                    }
                                }
                                <RELATIONSHIP_NAME> = val;
                            },
                            enumerable: true
                         });
                    },
                    removeReferences: function() {
                        // Only add this line if this is a subclass
                        arguments.callee.$.removeReferences.call(this);
        
                        // Set all source properties to null
                        this.<SOURCE_RELATIONSHIP_NAME> = null;
        
                        // Do this for all target relationships
                        for (var i = this.<TARGET_RELATIONSHIP_NAME>.length - 1; i >=0; i--) {
                            var o = this.<TARGET_RELATIONSHIP_NAME[i];
                            o.<REVERSE_RELATIONSHIP_NAME> = null;
                        }
                    },

                    toClassPair: function() {
                        return {ID: this.ID, className: this.cn};
                    },

                    toObject: function() {
                        var o = {};
                        o.ID = this.ID;
                        o.cn= this.cn;
                        // Do this for all primitive properties
                        o.<PROPERTY_NAME> = this.<PROPERTY_NAME>;
                        // Do this for all source relationships
                        o.<SOURCE_RELATIONSHIP_NAME> = this.<SOURCE_RELATIONSHIP_NAME> != null ? 
                            this.<SOURCE_RELATIONSHIP_NAME>.toClassPair() : null;
                        // Do this for all target relationships
                       o.<TARGET_RELATIONSHIP_NAME> = [];
                       for (var i = 0; i < this.<TARGET_RELATIONSHIP_NAME>.length; i++) {
                           var entity = this.<TARGET_RELATIONSHIP_NAME>[i];
                           o.<TARGET_RELATIONSHIP_NAME>.push(entity.toClassPair());
                       }
                       return o;
                    },

                    /*********************************************
                     * Start Boilerplate
                     */
                    save: function(callback) {
                        if (this.ID == null) {
                            this.api.createObject(this.toObject(),callback);
                        } else {
                            this.api.putObject(this.toObject(),callback);
                        }
                    },
                    remove: function(callback) {
                        this.api.removeObject(this, callback);

                    }
                    ,doLoad: function(){
                        if (this.isShell && !this.isLoading) {
                            this.isLoading = true;
                            var that = this;
                            this.api.findById(this.cn, this.ID, function() {
                                that.isShell = false;
                                that.isLoading = false;
                            });
                        }
                    }
                });
                /*
                 * End Boilerplate
                 *************************************************/

                // Define static variables and functions
                <SHORT_CLASS_NAME>.prototype._all = [];
                <SHORT_CLASS_NAME>.prototype._allIsLoaded = false;

                Object.defineProperty(<SHORT_CLASS_NAME>.prototype, "all", {
                    get: function() {
                        if(!<SHORT_CLASS_NAME>.prototype._allIsLoaded){
                            <SHORT_CLASS_NAME>.prototype._allIsLoaded = true;
                            this.api.getAllByName("<FULL_CLASS_NAME>", function(result){
                            });
                        }

                        return <SHORT_CLASS_NAME>.prototype._all;
                    },

                    enumerable: true
                });

                return <SHORT_CLASS_NAME>;
            });
    });
Clone this wiki locally