One of the advantages of string template engines such as JUST.js, jqueryTmpl or handlebarsjs over template engines based on a virtual DOM tree (VUE.js, angular) is a low threshold of entry and ease of use. It also seems to me that it is easier to integrate plugins for jquery with string template engines.
However, the ability to reactively bind the model data to a template is really a handy tool, and after I tried VUE.js and angular, I really missed that in my favorite JUST.JS template engine .
In the end, I decided to add one-way reactive data binding in JUST.JS, but in the end I got a solution that can be used with almost any string template engine.
Let's start with a simple example.
In it, we did without a template engine at all for simplicity and clarity of the code. In this example, a new value is assigned once per second to a variable. And then justReactive for you makes changes to the dom tree of the page. ')
The justReactive library adds the following methods for Object, each of which is intended to insert the monitored value into different places of the html code.
justHtml - display text or html code from a variable without any filtering
justText - display text from a variable as text, with html entities converting to text
justClass - substitutes the class if the value of the monitored variable is not false
justNotClass - substitutes the class if the value of the variable being tracked is false
justClassName — substitutes the value of the variable being tracked as a class
justAttr - substitutes and updates the attribute of the element
Operating principle
The following call:
model.justText('time')
will return the html code that you need to insert into the template at the place where your variable should be. It is redundant, that is, in addition to the value of the variable itself, we have to wrap it with additional elements.
So for example, justText will return the following html code:
Such redundancy sometimes interferes with the layout, but this is the price that is necessary for the possibility of further changing the value directly on the page. By performing a simple assignment.
It is also necessary to take into account the fact that after adding tracking of a variable, its value is replaced with an object with a hetero and a seter ( for those who do not know about this possibility ) and later on assignments they are called, so if you already use the functions of heteros and seters in your code then we need to think about the absence of conflicts.
Another usage example
This example is based on the previous one. Here we have added tracking of another model.class variable to change the class of an element and the model.hide variable to hide another element.
Disadvantages approach
This approach has a number of problems that need to be considered when working with code. In the following situation, we can get not what we wanted:
var model = {}; model.key1 = 1; $("#time1").html(model.justText('key1')) model = {key1:2};
In this example, the value in the dom tree will not be updated because the assignment in model = {key1: 2}; in fact, first deleted the model.key1 that we are tracking, and then created a new model object with the same, but not the same key, key1.
Cycles and blocks of patterns
To change the individual elements of what we have considered enough. But sometimes you want to work when changing one variable to rebuild a whole block of the template. For example, if we monitor an array and add another element to it, we want to rebuild the entire list of elements.
To solve this problem, we could immediately insert a large block of html code into one of the elements.
But even though this works, it is not very convenient. I personally made a fork of the just.js template engine and added a number of additional features to it along the way cutting out what seemed to me superfluous in it.
I called the resulting modified template engine just-template
In it, I added a structure to track the variables of the model that immediately rebuilds the template block that is attached to it. In this case, through the closure, all variables are transferred when the template is built for the first time.
And I completely cut out all the asynchrony since I only use it at the frontend and the lack of asynchrony greatly simplifies the code. And allows you to easily collect the final page in pieces by calling several different templates.
The final example with an array and cycles and pattern.