RainyJs - like Angular, only for Ajax

I am not a fan of bicycles. Before starting to develop my own solution to a trivial task in my opinion, I always spend a lot of time looking for existing libraries or modules. And not because my code will obviously be worse than the third-party one. Just why come up with what has already been created, verified and debugged. It is much better to spend time creating something new, hitherto not invented. However, this time I still had to sit down for the development myself. The article will focus on a convenient js-library that allows you to "bind" the data.

How it all started or what Angular is missing


First of all, I will list the problems that I had to face and which could not be solved by existing libraries. Examples will be given for Angular, but the same fully applies to Angular Light, and to many other libraries. So let's go ...

01) One way data binding


This is strange, but I still could not understand how to implement one-way data binding. In my work, I mainly use the Yii2 framework, and here's the simplest task: generate an input field and associate it with a block (div). It would seem simpler, but no: when generating inputa, although its value is set in it, angular does not take this value into account and takes the value of the "model", which is empty when the page loads.

Alternatively, you could use the “ng-init” directive (or “al-init” for Angular Light), and for the simplest cases the problem will really be solved. But there is one thing: if you use dynamic data updating components (such as Editable), the following is obtained: you change the value, save it => you need to update the binding => and when updating the binding, the value from "ng-init" is taken again, which is already not relevant. The trouble ...

02) Model-View-Controller


Now stones will fly at me, but I am against using the MVC scheme when displaying html pages.

For large and large projects with a complex structure - yes, for projects related to the display of graphics, where one element may require several types - yes, but using this mechanism when displaying simple pages - why? After all, the result is the following: the html-code of the element is in one place, the template for displaying it in another, and the controller is generally somewhere in the scripts at the top of the page. As a result, instead of a simple visual structure, it turns out to be something cumbersome and clumsy, where in order to copy any element for reuse in another project, you have to shovel the entire page and understand the whole logic of its functioning.

In my humble opinion, if you have, say, cool watches on your page, then all the logic of this element, including scripts and styles, should be in one place. Then, if you wish, you can easily select / copy / paste it - and voila, it also works in your other project, without any yaw on scripts and controllers.

03) Dynamic content loading


It was this problem that became the decisive factor for the start of developing our own solution. In fact, the previous paragraphs, in principle, can be solved through crutches and piles of unnecessary code. But with the updating of links after loading the contents, everything is sad.

Data binding in Angular, as you know, is only done when the page loads. But what if the content is generated dynamically or loaded via ajax requests, i.e. if you need to bind after the initial boot? The only way that it was possible to discover is using $ scope. $ Apply () in the controller. It would seem that a solution has been found? Not at all. The fact is that in the content that came from the server and loaded on the page, there can also be (and will be) elements that require data binding. How to be in this case? Do not shove all the possible site algorithms into one large mega-controller.
Or another example: what to do when there are blocks in the loaded content, the contents of which are also loaded or generated dynamically? I'm far from special in Angular, and maybe there are ways to accomplish these tasks. But most likely it will be far from simple and very cumbersome.

RainyJs - installation and quick start


The library is completely autonomous and in compressed form weighs only about 7Kb.

To use, just download the rainy.js file and connect it to your page.
The initial data binding, as in Angular, is done automatically when the page loads. But also data binding is performed when ajax-loading content, and in this case only the directly loaded fragment of the page is processed.

To "directly" update links (for example, after dynamically creating an element), you can call the rainy (elem) function , where you can pass a selector, dom element, or even a jQuery object as a parameter. If you call this function without parameters, then the links will be updated on the entire page.

Basic Data Binding Directives


Now the library contains only 12 directives, which makes it quite easy to learn.

The main directives are “rxname” and “rxdata” . The first is installed in the source element and sets the variable name, the second is set in the receiver element and indicates the name of the variable from which data is to be taken. If data needs to be obtained from several sources, then a list of variable names is placed in rxdata separated by a space.

An example of use is given below:



Hello, !

[Edit]

Prefixes and postfixes in display


Quite often, webmasters need to slightly adjust the resulting display (for example, add the “rub.” Postfix for the amount entered). For such formatting, you can use the rxview directive , inside which you can use the following patterns (patterns are written in double curly brackets):

  • {{rxname}} - the name of the source variable that has been changed
  • {{value}} - the resulting value that would be displayed without formatting
  • {{var01}} - the value of a variable named "var01" (used if there are several sources)

An example of use is given below:



[Edit]

Show / Hide data block


Another common task is to display / hide a text block by a check box or by some condition. A separate rxshow directive is reserved for these purposes . As its value, you can put either the name of the variable or the js-code of the trigger condition.

An example of use is given below:


Этот текст будет виден только при установленном флажке.

[Edit]

Executing any code on an element


The next directive to be discussed is rxcode . It is intended for more complex options for data binding and is a js-code that will be executed in the receiver element before updating its contents. Here you can either override the set value by simply returning a new one, or cancel the change altogether by returning undefined .

Also, this directive is used to execute absolutely any code on an element. For example, you can change the class of an element or make it inaccessible through it. I know, I know that angular has separate directives for this, and to change the class you just need to set the attribute value. I admit, I also had thoughts about this, but in the end I decided not to produce extra parameters, because simplicity is the key to success.

The following variables are available inside rxcode:

  • sender - dom-element from which the event came
  • rxname - name of the variable whose value has been changed
  • values - an array of values ​​of variables specified in rxdata
  • value - the value of the first variable from the array [values]
  • self - current dom element (event receiver)

An example of use is given below:




[Edit]

Ajax loading element content


And finally, we came to the most important thing, for which, in fact, the library was created. There are also only two directives that can be set in the receiver: “rxajax” and “rxload” .

In [rxajax], you should specify the path to the script that returns the new content, ie request template. This request is sent using the GET method, and the JSONP format is used for data transfer. You can use the same wildcard patterns in the request text as in the rxview directive.

The rxload directive may contain js code that will be executed after loading new content into an element. It is worth noting that this directive can be used not only for ajax-loading content, but also for any other elements. This can be very useful, for example, when using jQuery plugins, since most of them “connect themselves to the elements” only at the initial page load.

An example of using “rxajax” is given below:


[Edit]

A few more use cases


This library is designed for one-way data binding, however, organizing two-way binding is also not a special problem:

	Двустороннее связывание данных:



[Edit]

Sometimes the “Select All” checkbox is simply necessary. Now it’s as simple as that:

 Выделить все
Флажочек №1
Флажочек №2
Флажочек №3

[Edit]

And another rather interesting example: when the price or quantity changes, the amount is automatically recalculated, and when the amount changes, the price is automatically set:


[Edit]

Instead of a conclusion


I am a supporter of dynamically developing projects, so I will be glad to any tips and suggestions for improving the code. The only thing to keep in mind is that costs should be commensurate with added capabilities. For example, writing a bunch of lines of code to support IE6 makes little sense to me. Just because if a potential client still uses such junk - this is definitely not our client.

Links to external resources


x-rainy.org - official site of the library

Also popular now: