vue-mc icon indicating copy to clipboard operation
vue-mc copied to clipboard

defineProperty with configurable

Open mrFANRA opened this issue 6 years ago • 3 comments

Im trying overwrite getters&setters for simple relations support, but get error can't redefine non-configurable property. Can you add please configurable: true, in registerAttribute for Object.defineProperty?

mrFANRA avatar Feb 04 '18 23:02 mrFANRA

I'm curious to see what you're trying to implement here. Would you mind sharing your code and concept? Might be a good case to support natively here.

rtheunissen avatar Feb 05 '18 03:02 rtheunissen

Its very simply, but work for me ...

BaseModel

constructor(attributes = {}, collection = null, options = {}) {
        super(attributes, collection, options);

        Vue.set(this, '_relations', {}); // Relations
        this.assignRelations();
}

get relations() {
    return this._relations;
}

definedRelations(){return {}}

setRelation(name, config, relation){
    if (relation && _.isPlainObject(relation)) {
        relation = new config.class(relation);
    }

    var foreignKey  =   config.foreignKey || `${name}_id`;
    var localKey    =   config.localKey || 'id';

    Vue.set(this._relations, name, relation);
    var value = (relation)?relation[localKey]:null;
    this.set(foreignKey,value);

    return this;
}

getRelation(name){
    return this._relations[name];
}

registerRelation(name,config){
    var _that = this;
    var names = _.unionBy([name],config.aliases);

    _.each(names,function (item) {
        var exist = !_.isUndefined(_that[item]); // I can't find how to set Relations before super() method.

        Object.defineProperty(_that, item, {
            get: ()         => _that.getRelation(name),
            set: (relation) => _that.setRelation(name, config, relation),
        });

        if (exist){
            _that[item] = _.cloneDeep(_that.get(item));
            _that.unset(item);
        }
    });

    return this;
}

assignRelations(){
    let that = this;
    _.each(this.definedRelations(),function (config, name) {
        that.registerRelation(name,config);
    });
}

Model

definedRelations(){
    return {
        contractor:{class:ContractorModel},
        category:{class:CategoryModel},
        town_from:{class:GeographyModel,foreignKey:'from_town_id',aliases:['townFrom']},
        b_point_profile:{class:BPointsProfilesModel,foreignKey:"bpoint_profile_id",aliases:['BPointProfile']},
        avatar:{class:AvatarModel},
        s_c_offer:{class:SCOfferModel,foreignKey:"scoffer_id",aliases:['SCOffer']},
    }
}

Usage

var offerModel = new OfferModel();
var contractorModel = new ContractorModel({id:123,...});

offerModel.contractor = ContractorModel;
console.log(offer.contractor_id); // 123

mrFANRA avatar Feb 05 '18 06:02 mrFANRA

Can't see a reason why configurable can't be true. 👍

rtheunissen avatar Feb 18 '18 21:02 rtheunissen