serializable-es5

1.0.5 • Public • Published

serializable-es5

A serialization utility that automatically serialize and de-serialize Class instance. It makes saving and restoring process of modular application much easier.

NPM version Build Status Clean Code Dependency Status devDependency Status License

Browser support

Desktop: Chrome, Safari, Firefox, Opera, IE9+

Installation

    npm install serializable-es5
 
    or 
 
    jspm install npm:serializable-es5

Usage

An example :

 
    var Serializable = require('serializable-es5');
 
 
    /**
    * Assume we are developing a shopping website,
    * And we have a page contains a list of items
    * that a user is going to buy.
    */
    var Cart = function (domParent) {
        this._items  = [];          // Cart items.
        this._parent = domParent;
 
        this._buildUI();
    };
 
    /**
    * Property '_serializeInfo' must be provided because
    * Serializable utility recognize an object as serializable by 
    * checking the existence of this property.
    */
    Cart._serializeInfo = [
        '_items',           
        '_dataTable',
        '_nonExist',        // Non-exist property will be skipped during serialization.
        '_finalize'
    ];
 
    Cart.prototype = {
        constructor: Cart,
 
        /**
        * When this method is called, Serializable.serialize() will scan 
        * Cart._serializeInfo and if an element of this array is :
        *
        *   1. A property, then the value of this property will be simply returned (if 
        *      the value is of type String, Number, .etc), or be deep cloned then returned 
        *      (if the value is of type Object, Array, etc.)
        *   2. A function, then it will check whether this function name has prefix '_serialized' 
        *      , it will execute this function if it has, otherwise it will simply 
        *      skip it. ( Be noted that a function with no prefix '_serialized' will still be 
        *      executed during deserialization process. )
        *
        *   // The structure of return value of this method will be like this :
        *
        *   {
        *       _ : {
        *           className:    'Cart',
        *           purpose:      'save',           // By default is saving purpose.
        *           isSerialized: true
        *       },
        *
        *       info: {
        *           _items: Array,    // An array of item objects. ( is a deep-copied list.)
        *           
        *           // The value of _dataTable has the same structure as Cart instance's , 
        *           // Since DataTable Class also implemented _serializeInfo interface.
        *
        *           _dataTable:     {                   
        *                               _ : {
        *                                   className:    'DataTable',
        *                                   purpose:      'save',
        *                                   isSerialized: true
        *                               },
        *                               info: {
        *                                   _serializedAltRowColor: Boolean
        *                               }
        *                           }
        *       }
        *   };
        *
        */
        serialize: function () {
            /**
            * serialize() method takes two arguments :
            *   argument 1. it is usually the instance itself.
            *   argument 2. Class name in String.
            */
            return Serializable.serialize(this, 'Cart');
        },
 
        _buildUI: function () {
            /**
            * You can ignore this.
            */
            this._domContainer = $('<div>').appendTo(this._parent)
                                           .addClass('cart');
            this._header = $('<div>').appendTo(this._domContainer)
                                     .addClass('hdr')
                                     .text('My Cart');
            /**
            * Create DataTable instance.
            */
            this._dataTable = new DataTable(this._domContainer);
        },
 
        /**
        * Add an item to the list.
        */
        add: function (item) {
            this._items.push(item);
            this._loadList();          
            return this;
        },
 
        _loadList: function () {
            this._dataTable.load(this._items);  // Reload data table with new list.
        },
 
        /**
        * If user changed row-alternative-color settings.
        * Reload data table to reflect this change.
        *
        * You can ignore this method, just remember this setting is 
        * important to the users and we will save it.
        */
        altRowColor: function (enableAltRowColor) {
            if (typeof enableAltRowColor === 'boolean') {
                if (this._dataTable.altRowColor() !== enableAltRowColor) {
                    this._dataTable.altRowColor(enableAltRowColor);
                    this._loadList();
                }
            }
            else if (typeof enableAltRowColor !== 'undefined')
                throw "IllegalArgumentException: enableAltRowColor must be a Boolean.";
 
            return this;
        },
 
        /**
        * This method will only be called during deserialization.
        * This is useful after all data is restored from deserialization and 
        * you might want to do some last step operation, e.g. resize this 
        * instance, etc.
        *
        * ( A function which has a name with prefix '_serialized' will be 
        *   called during both serialization and deserialization, otherwise it 
        *   will only be called during deserialization. )
        */
        _finalize: function () {
            this._loadList();   // Items are already restored we reload the list.
            this._resize();     // Data list are loaded, you might want to resize.
        }
    };
 
 
    /**
    * DataTable class is incomplete, but since I am just showing 
    * the usage of Serializable utility, I am not going to complete 
    * this class.
    */
    var DataTable = function (domParent) {
        this._altRowColor = false;
    };
 
    DataTable._serializeInfo = [
        '_serializedAltRowColor'   
    ];                             
 
    DataTable.prototype = {
        constructor: DataTable,
 
        altRowColor: function (isAltRowColor) {
            if (typeof isAltRowColor === 'boolean')
                this._altRowColor = isAltRowColor;
            else 
                return this._altRowColor;
        },
 
        /**
        * Assume this method will load all data to doms and 
        * show it to user.
        */
        load: function (rows) {
        },
 
        /**
        * You don't need to call this method explicitly,
        * this method will be called when 'Serializable' utility recognizes that 
        * the value of Cart._dataTable is an instance of DataTable class which 
        * implemented serializable interface ( has '_serializeInfo' ).
        */
        serialize: function () {
            return Serializable.serialize(this, 'DataTable');
        },
 
        /**
        * This method will be called during both serialization and deserialization.
        */
        _serializedAltRowColor: function (serialized) {
            /**
            * Deserialization.
            */
            if (typeof serialized === 'boolean') {
                this._altRowColor = serialized;
                /**
                * You might add more code here.
                */
            }
            /**
            * serialization.
            */
            else {
                return this._altRowColor;
            }
        }
    };
 
 
 
    // Create Cart instance.
    var cart = new Cart(document.body);
 
    // Fake data.
    var getItem = function (name, price) {
        return {
            type: 'fruit',
            weight: '1kg',
            name: name,
            price: price
        };
    };
 
    // Assume we have a button.
    $('#btn-add-item').bind('click', function () {
        var item = getItem('apple', 30);
        cart.add(item);
    });
 
    cart.add( getItem('orange', 12) )
        .add( getItem('banana',  6) )
        .add( getItem('lemon',   8) );
 
    /**
    * Now you have a copy of serialized cart data,
    * you can save it to a database table or anywhere you want.
    */
    var dataToSave = JSON.stringify( cart.serialize() );
 
    /**
    * Restore data is as easy as serialization.
    * @return {Cart} - a Cart instance.
    */
    var cart = Serializable.deserialize( JSON.parse(dataFromDB) );
 
    /**
    * You can also provide a cart instance as the 2nd argument, 
    * but this is optional. If omitted, a cart instance will be 
    * created during deserialization and finally returned. If provided,
    * the same instance will be returned.
    */
    var cart = Serializable.deserialize( JSON.parse(dataFromDB), cartInstance );
 

Public properties and methods :

Tests

    npm test

Todo

  • Add the document of public interfaces 🎈
  • Add test.

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 1.0.5
    0
    • latest

Version History

Package Sidebar

Install

npm i serializable-es5

Weekly Downloads

0

Version

1.0.5

License

MIT

Last publish

Collaborators

  • wenwu