HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

PubSub and two-way data binding

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
andwaytwobindingpubsubdata

Problem

I looked up how to use the PubSub pattern in JS and came across a few articles. I wanted to have two way data binding, so when a one of an Object's Properties value was set, it would update x number of subscribers.

It sounds confusing, but here's the relevant sections of my code:

// data-cluckles-jumbotron="padding" adds the input to the subscribers array
// in clucklesEditor.jumbotron.padding.subscribers
// In context Jumbotron is a constructor function, padding is a property
// So this.padding = {}


Here's the Jumbotron constructor function. As you can see it inherits from ThemeModifiers, which is where the two way data binding, and the PubSub is setup.

var Jumbotron = function (editor) {
    ThemeModifier.call(this, editor); // Call parent constructor

    this.subscriberDataAttribute = 'data-cluckles-jumbotron';

    // Configure the Modifiers
    this.bg = {
        variable:           '@jumbotron-bg',
        subscribeProperty:  'bg',
        changeFn:           this.setBackgroundColor.bind(this),
        subscribers:        [],
        _value:             null
    };

    this.setupDataBinding();
};

// Inherit from parent Prototype and preserve constructor
Jumbotron.prototype             = Object.create(ThemeModifier.prototype);
Jumbotron.prototype.constructor = Jumbotron;

Jumbotron.prototype.setBackgroundColor = function (backgroundColor) {
    this.modifiers.bg.value = backgroundColor;
};


Now here's ThemeModifiers. I have stripped out the non relevant parts:

```
var ThemeModifier = function (editor) {
Object.defineProperties(this, {
'editor': {
enumerable: false,
value: editor
},
'modifiers': {
enumerable: false,
writable: true,
value: {}
}
});
};

/**
* Configured the Two Way Databinding for the modifiers, which includes
* binding multiple DOM Element subscribers which have the "data-cluckles-{{type}}" attribute,
* which ma

Solution

From a once over;

  • I would have put the articles URL's you read in the comments up to



-
Your commenting within the functions is too often obvious, like here:

// Get the modifier object
var modifier = this.modifiers[modifierName];


  • Jumbotron constructor looks good to me, HTML as well



-
This

if (suffixUnit) {
    // Call the change function and provide the extra suffix
    modifier.changeFn(e.target.value, suffixUnit);
} else {
    // else call change function as default
    modifier.changeFn(e.target.value);
}


is equivalent to

modifier.changeFn(e.target.value, suffixUnit || undefined );


-
This

var unit = 'px'; // Default unit to append (px, em, rem, etc)

            // If this property requires a suffix unit
            if (this.suffixUnit) {
                // Store the raw value
                this._rawValue = val;

                // If a custom unit is specified
                if (this.unit) {
                    // Set the unit to append
                    unit = this.unit;
                }

                // Combine the value with the unit
                this._value = val + unit;
            } else {
                // Store the new value
                this._value = val;
            }


is equivalent to

if (this.suffixUnit) {
                this._rawValue = val;
                this.value = val + ( this.unit || 'px' );
            } else {
                this._value = val;
            }


All in all, I still think I would go for a more known library. But I salute you for writing a readable two-way data binding solution.

Code Snippets

// Get the modifier object
var modifier = this.modifiers[modifierName];
if (suffixUnit) {
    // Call the change function and provide the extra suffix
    modifier.changeFn(e.target.value, suffixUnit);
} else {
    // else call change function as default
    modifier.changeFn(e.target.value);
}
modifier.changeFn(e.target.value, suffixUnit || undefined );
var unit = 'px'; // Default unit to append (px, em, rem, etc)

            // If this property requires a suffix unit
            if (this.suffixUnit) {
                // Store the raw value
                this._rawValue = val;

                // If a custom unit is specified
                if (this.unit) {
                    // Set the unit to append
                    unit = this.unit;
                }

                // Combine the value with the unit
                this._value = val + unit;
            } else {
                // Store the new value
                this._value = val;
            }
if (this.suffixUnit) {
                this._rawValue = val;
                this.value = val + ( this.unit || 'px' );
            } else {
                this._value = val;
            }

Context

StackExchange Code Review Q#63266, answer score: 3

Revisions (0)

No revisions yet.