2

I need to implemennt data binding or any other kind of variable observer, whenever the variable changes, trigger some defined action. We are also talking about pure JS, I do not want to use any kind of framework or library due to the performance issues.

I have found a pretty simple and nice data binding code, but its behavior is quite wierd. It works only if you try to bind only 1 variable. Whenever you try to bind multiple variables, it will bind all actions to the last element, even if the bindings was called separately to different variables.

function Binding(b) {
	_this = this
	this.element = b.element
	this.value = b.object[b.property]
	this.attribute = b.attribute
	this.valueGetter = function(){
		return _this.value;
	}
	this.valueSetter = function(val){
		_this.value = val
		_this.element[_this.attribute] = val
	}

	Object.defineProperty(b.object, b.property, {
		get: this.valueGetter,
		set: this.valueSetter
	});	
	b.object[b.property] = this.value;
	
	this.element[this.attribute] = this.value
}


var obj = {a:123, b:456, c:789};
var myElement = document.getElementById("myText");
var a = new Binding({
	object: obj,
	property: "a",
	element: document.getElementById("myText"),
	attribute: "value",
});

var b = new Binding({
	object: obj,
	property: "b",
	element: document.getElementById("myText2"),
	attribute: "value",
});

var c = new Binding({
	object: obj,
	property: "c",
	element: document.getElementById("myText3"),
	attribute: "value",
});

setInterval(function(){
for(var key in obj)
{obj[key]++;} }, 1000);
<input type=text id="myText"/>
<input type=text id="myText2"/>
<input type=text id="myText3"/>

Any idea please, how to alter the code in such a way, that I can bind the variables separately? I have tried to play with .bind() like if the "this" is overwriting something, I tried to play with rewriting function Bind to class, but so far with no results ...

Any help appreciated, thanks!

2

1 Answer 1

1

Just use arrow functions to avoid redefining "this" and to avoid having to hack around it with a global variable:

function Binding(b) {
    this.element = b.element
    this.value = b.object[b.property]
    this.attribute = b.attribute
    this.valueGetter = () => {
        return this.value;
    }
    this.valueSetter = (val) => {
        this.value = val
        this.element[_this.attribute] = val
    }

    Object.defineProperty(b.object, b.property, {
        get: this.valueGetter,
        set: this.valueSetter
    }); 
    b.object[b.property] = this.value;

    this.element[this.attribute] = this.value
}

You could also use const, let, or var when defining _this, as a patch on top of your _this hack. But arrow functions avoid the _this hack in the first place. They're designed to avoid the scoping issues that led to the _this hack.

Sign up to request clarification or add additional context in comments.

6 Comments

Worth noting: Arrow functions are not supported in Internet Explorer or Opera Mini
@Riddell Opera Mini. Opera itself supported arrow functions pretty much since ES6 came out. It's running on Chromium, so it's hard to not be up to date with web standards there.
Opera has supported arrow functions since 2015. But yes, if you need to support every browser on every device, you might need to set up an ES6 to ES5 compilation step to support modern Javascript syntax.
Yes sorry, I was on two questions at once. That was typo. I've updated the comment
This sounds like it's a new project, so it's probably best to avoid starting the project with the technical debt of archaic Javascript syntax, especially for something fundamental like the data binding API.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.