From 4ef22bddf05ca24005dcfb97a0e96d4d61854bb2 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 28 Dec 2017 00:12:11 +0100 Subject: [PATCH] Refactor TraitView and sync it with target changes. Closes #686 --- src/trait_manager/model/Trait.js | 45 ++++++++++++++++++++++++++--- src/trait_manager/view/TraitView.js | 44 +++++++++++++++++----------- 2 files changed, 68 insertions(+), 21 deletions(-) diff --git a/src/trait_manager/model/Trait.js b/src/trait_manager/model/Trait.js index 0f55687c7..adec39da0 100644 --- a/src/trait_manager/model/Trait.js +++ b/src/trait_manager/model/Trait.js @@ -1,6 +1,6 @@ -var Backbone = require('backbone'); +import { isUndefined } from 'underscore'; -module.exports = Backbone.Model.extend({ +module.exports = require('backbone').Model.extend({ defaults: { type: 'text', // text, number, range, select @@ -16,13 +16,50 @@ module.exports = Backbone.Model.extend({ options: [], }, + initialize() { - if (this.get('target')) { - this.target = this.get('target'); + const target = this.get('target'); + const name = this.get('name'); + const changeProp = this.get('changeProp'); + + if (target) { + this.target = target; this.unset('target'); + const targetEvent = changeProp ? `change:${name}` : `change:attributes:${name}`; + this.listenTo(target, targetEvent, this.targetUpdated); + } + }, + + + targetUpdated() { + const value = this.getTargetValue(); + !isUndefined(value) && this.set({ value }, { fromTarget: 1 }); + }, + + + getTargetValue() { + const name = this.get('name'); + const target = this.target; + const prop = this.get('changeProp'); + if (target) return prop ? target.get(name) : target.getAttributes()[name]; + }, + + + setTargetValue(value) { + const target = this.target; + const name = this.get('name'); + if (isUndefined(value)) return; + + if (this.get('changeProp')) { + target.set(name, value); + } else { + const attrs = { ...target.get('attributes') }; + attrs[name] = value; + target.set('attributes', attrs); } }, + /** * Get the initial value of the trait * @return {string} diff --git a/src/trait_manager/view/TraitView.js b/src/trait_manager/view/TraitView.js index 607ace50b..c5e843cce 100644 --- a/src/trait_manager/view/TraitView.js +++ b/src/trait_manager/view/TraitView.js @@ -1,3 +1,6 @@ +import { isUndefined, clone } from 'underscore'; + +const Backbone = require('backbone'); const $ = Backbone.$; module.exports = Backbone.View.extend({ @@ -11,20 +14,23 @@ module.exports = Backbone.View.extend({ }, initialize(o) { - var md = this.model; + const model = this.model; + const name = model.get('name'); + const target = model.target; this.config = o.config || {}; this.pfx = this.config.stylePrefix || ''; this.ppfx = this.config.pStylePrefix || ''; - this.target = md.target; + this.target = target; this.className = this.pfx + 'trait'; this.labelClass = this.ppfx + 'label'; - this.fieldClass = this.ppfx + 'field ' + this.ppfx + 'field-' + md.get('type'); + this.fieldClass = this.ppfx + 'field ' + this.ppfx + 'field-' + model.get('type'); this.inputhClass = this.ppfx + 'input-holder'; - md.off('change:value', this.onValueChange); - this.listenTo(md, 'change:value', this.onValueChange); + model.off('change:value', this.onValueChange); + this.listenTo(model, 'change:value', this.onValueChange); this.tmpl = '
'; }, + /** * Fires when the input is changed * @private @@ -37,22 +43,26 @@ module.exports = Backbone.View.extend({ return this.model.get('value'); }, + + setInputValue(value) { + this.getInputEl().value = value; + }, + + /** * On change callback * @private */ - onValueChange() { - var m = this.model; - var trg = this.target; - var name = m.get('name'); - var value = this.getValueForTarget(); - // Chabge property if requested otherwise attributes - if(m.get('changeProp')){ - trg.set(name, value); - }else{ - var attrs = _.clone(trg.get('attributes')); - attrs[name] = value; - trg.set('attributes', attrs); + onValueChange(model, value, opts = {}) { + const mod = this.model; + const trg = this.target; + const name = mod.get('name'); + + if (opts.fromTarget) { + this.setInputValue(mod.get('value')); + } else { + const value = this.getValueForTarget(); + mod.setTargetValue(value); } },