eliace/ergo-js

View on GitHub
js/data/object.js

Summary

Maintainability
C
7 hrs
Test Coverage


/**
 * Источник данных как объект.
 *
 *
 * @class
 * @name Ergo.data.Object
 * @extends Ergo.core.DataSource
 */
Ergo.defineClass('Ergo.data.Object', /** @lends Ergo.data.Object.prototype */{

    extends: 'Ergo.core.DataSource',

    defaults: {
        idKey: 'id',
        oidKey: 'id'
    },

    /**
     * Определение полей объекта
     */
    fields: {
    },




    _oid: function() {
        return this.get(this.options.idKey);
    },

    get oid() {
        return this.get(this.options.oidKey);
    },

    // oid: function() {
    //     return this.get(this.options.idKey);
    // },

    // /**
    //  * Метод валидации
    //  * @function
    //  */
    // validate: null,



    _initialize: function(o, v) {
        if(arguments.length == 0)
            this._super({});
        else if(arguments.length == 1) {
            this._super({}, o);
        }
        else
            this._super.apply(this, arguments);
    },




    set: function(v) {

        // если значение устанавливается именно для нас
        if(arguments.length == 1) {

            if(this.options.readonly) return;

            var validator = this.options.validator || this._validate;

            if(validator) {
                if( validator.call(this, v) === false ) {
                    this.events.fire('invalid', {value: v, entry: this});
                    return;
                }
                else {
                    this.events.fire('valid', {value: v, entry: this});
                }
//                    throw new Error('Invalid value: ['+v+']');
            }
        }

//        return this._super.apply(this, arguments);
        return Ergo.data.Object.superclass.set.apply(this, arguments);
    },


    /**
     * Подгрузка данных
     *
     *
     */
    fetch: function(id, q) {

        if (id == null || $ergo.isObject(id)) {
            id = this.oid;
        }

//        this._fetched = true;
        var parser = this.options.parser || this._parse;
        var provider = this.options.provider;
        var query = Ergo.merge({}, this.options.query, q);

        if( $.isString(provider) )
            provider = Ergo.alias('providers:'+provider);

        this.events.fire('fetch', {query: query, id: id});

        if(provider) {
//            var self = this;
            return provider.find(this, id, query).then(function(data) {
                this.set( parser.call(this, data) );
                this._fetched = true;
                this.events.fire('fetched');
                return data;
            }.bind(this));
        }
        else {
            this._fetched = true;
            this.events.fire('fetched');
        }

    },


    /**
     * Обработка "сырых" данных
     *
     */
    _parse: function(v) {
        return v;
    },





    flush: function() {

        var oid = this.oid;

        var composer = this.options.composer || this._compose;
        var parser = this.options.parser || this._parse;
        var provider = this.options.provider;

        this.events.fire('flush');

        if( $.isString(provider) )
            provider = Ergo.alias('providers:'+provider);

        if(provider) {

            // create
            if(oid == null) {

                var data = composer.call(this, this.get(), 'create');

                return provider.create(this, data, this.options.query)
                    .then(function(data) {
                        this.events.fire('flushed');
                        return parser.call(this, data, 'create');
                    }.bind(this));
            }
            // update
            else {

                var data = composer.call(this, this.get(), 'update');

                return provider.update(this, oid, data, this.options.query)
                    .then(function(data) {
                        this.events.fire('flushed');
                        return parser.call(this, data, 'update');
                    }.bind(this));
            }
        }
        else {
            this.events.fire('flushed');
        }

        return $.when(null);
    },


    _compose: function(v) {
        return v;
    },



    drop: function() {

        var oid = this.oid;

        this.events.fire('drop');

        if( $.isString(provider) )
            provider = Ergo.alias('providers:'+provider);

        if(provider) {

            return provider.delete(this, oid)
                .done(function(data) {
                    this.events.fire('dropped');
                    return data;
                }.bind(this));

        }
        else {
            this.events.fire('dropped');
        }


        return $.when(null);
    },





    // invoke: function(action) {
    //
    //     var oid = this._oid();
    //
    //     var provider = this.options.provider;
    //     var composer = this.options.composer || this._compose;
    //
    //     if( $.isString(provider) )
    //         provider = Ergo.alias('providers:'+provider);
    //
    //     if(provider) {
    //
    //         var data = composer.call(this, this.get(), action);
    //
    //         return provider[action](this, oid, data, this.options.query).then(function(data) {
    //             // ?
    //             return data;
    //         });
    //     }
    //
    // },




//    get: function() {
//        var v = this._super.apply(this, arguments);
//        var v = Ergo.data.Model.superclass.get.apply(this, arguments);

//        return (this.format) ? this.format.call(this, v) : v;
//    },





    /**
     * Фабрика элементов модели (полей).
     */
    _factory: function(i) {

        /**
         * Фабрика должна создавать элементы с помощью функции-генератора класса.
         * Причем, могут быть такие случаи:
         *  - задана сама функция
         *  - задано имя класса
         *  - задано поле, которое содержит псевдоним класса
         */

        var obj = this.fields[i];
        var o = {};
//        if($.isFunction(model)) model = model.call(this, this.val()[i]);
        if($.isPlainObject(obj)) {
            o = obj;
            obj = obj.etype;
        }
        if($.isFunction(obj) && !$ergo.isClass(obj))
            obj = obj.call(this, this.get()[i]);
        if(typeof obj === 'string')
            obj = Ergo.alias(obj);// || obj); //TODO здесь лучше загружать класс по зарегистрированному имени
        obj = obj || Ergo.core.DataSource;

        o.provider = this.options.provider;

        return new obj(this, i, o);
    }

}, 'data:object');