📜 ⬆️ ⬇️

Two small functions that can simplify life

I know about Backbone.js and Knockout.js
Just sometimes you want something much smaller.

1. Introduction. What are we talking about, what is the subject area. What is the problem.

What it is about: there is JavaScript, "spherical, in a vacuum."
Subject area: objects and their properties, that is defined by the following methods.
')
var obj = new Object(); var obj = {}; 


where properties, respectively:

 obj.prop = 111; obj = { "prop1" : "value1" "prop2" : 2 } 


What is the problem:

1. There are such objects, they have these very properties.
2. I want to know when the property was changed (part of the MVVM pattern)
3. And, accordingly, subscribe to this change.

UPD 1 - Example in work , thanks alist , for a very, in my opinion, important comment below .



2. In detail, what is the problem to be solved.

Actually, this is the task, to subscribe to changes in properties, and call a function that can do something with this new property value. Let it be at the most "elementary" level. It is enough to track the change of simple properties: numbers, strings, boolean. That is, we may not even need properties with nested arrays, objects and functions.

Even such a simple “signing with callback” on such simple properties can already significantly reduce development time. For example, you can hang a trigger to receive new data from the socket, or subscribe to change any property in the model, which is visually displayed on the page.

3. Analogs. Existing solutions to the problem, what are their pros and cons

I did not look for a lot, for Backbone.js and Knockout.js are enough for heavy things.

So this is by no means an analogue for them, so a stub for elementary operations, or simply if these libraries "do not participate" in the code.

4. Description of the solution to the problem.

On the knee overnight, I reassembled two functions that are capable, respectively, in different ways, with one success or another, with their pros and cons to solve a similar problem:

warp (obj, prop, setcallback, interval)

observe (value, setcallback)

Plus observe ():
- short syntax
- no timeouts, getters and other things
- elementary as an ax, will work wherever there is a JS
Minute observe (): instead of just the properties, there will be a function, and you need to remember this.

Plus warp (): really subscribes to a real property, i.e. you can simply assign new values ​​to the property inside the object.
Cons warp ():
- bulk syntax.
- if the browser is “old”, without getters and setters, then the change tracking intervals will heavily load it with the missing “interval”.
- I did not check if the interval is reset when the property is deleted, in theory it should.

5. Conclusion. Why it is worth using and when, and when it is not.

This can be used if you want to do something simple, not requiring a “concept”.

Everything is very unpleasant:

warp - subscribes to properties with a callback to set.

observe - replaces the property with a function with a callback to set.

A little explanation under this code plate.

An example is to insert an empty HTML file.

 <textarea id = "context" cols = "70" rows = "15"></textarea> 


 try{ var info = function(str){ var x = document.getElementById('context'); if(str !== undefined){ x.value += str + '\n'; } else{ x.value = ' '; } try{ x.scrollTop = x.scrollHeight;; }catch(e){ } } var warp = function( obj, prop, setcallback, interval ){ try{ var val = obj[prop]; if( !obj ){ obj = window; } if(Object.defineProperty){ Object.defineProperty( obj, prop, { get : function () { try{ return obj[prop]; }catch(e){ return; } } , set : function ( value ) { try{ val = value; if(setcallback){ if(interval) { window.setTimeout( function(){ setcallback( value, prop, obj ); }, interval); }else{ setcallback( value, prop, obj ); } } return val; }catch(e){ return; } } }); }else{ if(!interval){ interval = 1000; } var intvl = window.setInterval( function(){ if(obj[prop] !== undefined){ if( val != obj[prop] ){ val = obj[ prop ]; if( setcallback ){ setcallback( val, prop, obj ); } } }else{ window.clearInterval( intvl ); } }, interval); } }catch(e){ return; } } var observe = function( value , setcallback ){ return function( val ){ try{ if( val !== undefined ){ if( val != value ){ value = val; if( setcallback ){ setcallback( value ); } } }else{ return value; } }catch(er){ alert(er); } }; } var obj = { prop : 111, observe : observe ( 222, function( val ){ info( 'observe : ' + val ); } ) }; warp( obj, 'prop', function( val ){ info( 'callback for prop : ' + val ) }, 100 ); var count1 = 0; window.setInterval( function(){ count1++; obj.prop = count1; }, 5000 ); var count2 = 0; window.setInterval( function(){ count2++; obj.observe( count2 ); }, 1000 ); window.setInterval( function(){ info( 'observer lookup : ' + obj.observe() ); } , 2000 ); }catch(e){ alert(e); } 


UPD 0 is a brief reference.

I will try to tell you how I use it, in steps.
1. Let there be some object.
2. It has some property, string, number, or boolean.
3. I want to know when it will change, and subscribe to this change with a callback that will accept the new value.

For this I use warp (obj, prop, setcallback, interval)

Where:
obj - the same object
prop is the property
setcallback is the same callback that will receive the changed value.
interval - if I want the callback to work with a delay.

This is what the warp was about.

As for observe: the situation is similar, but it is enough for me not to really listen to the property but to replace it with a function.
Then:
1. Have an object
2. There is a property
3. I substitute its function by
observe (value, setcallback)

after which the setting of the new value will look like
obj.my_property ('new value');
and reading the same value as obj.my_property ();

Readable sorts about getters and setters:
http://robertnyman.com/javascript/javascript-getters-setters.html#regular-getters-and-setters

https://developer.mozilla.org/en/JavaScript/Reference/Operators/get

https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects#Defining_Getters_and_Setters

But everything should work without this feature.

Source: https://habr.com/ru/post/140306/


All Articles