📜 ⬆️ ⬇️

Javascript Interface Abstract Notation

Hello everyone, this post about the library, or rather the philosophy of developing applications for Javascript that invented a couple of months ago. I constantly use it myself, I distributed it to all my friends. The feedback was positive, so I decided to risk opening up to the wider community.
The library itself works like a jQuery tweak. Practically, the dependence on jQuery is conditional and can be shared with the library itself until it was necessary.
Jiant allows you to create client applications of any complexity, greatly simplifying their support and development.

Brief background


I have been developing web applications for over 10 years. The last couple of years I have been using GWT all the time. Unfortunately, Google could not solve the most serious problem of this library - slow compilation. After a long pause in the release of new versions (between 2.4 and 2.5) and the transfer of GWT to the side, the leading developers of the company where I work (not widely known) agreed that it is time to tie up with GWT. We decided to continue to develop on jQuery. But GWT instilled some very handy "reflexes" of development, which were clearly lacking with pure javascript programming. In particular, the MVC approach is divided into presentation and logic, EventBus. The inconvenience and discomfort of the new situation led to some ideas that, gradually evolving and transforming, led to the solution described below.
Also, before writing the library, I was dealing with existing MVC solutions like Backbone and was not very happy with the number of boilerplate codes (redundancy of the required announcements).

Benefits


Actually, in order to have an incentive to read, I run ahead and list the main advantages:
  1. Code completion (autocomplete) - instead of string declarations.
  2. Complete interface abstraction and separation of logic and presentation
  3. Validation of javascript bindings of variables to the actual elements of a web page during application launch, and not during the execution of a specific code fragment. What gives additional protection to the developer of the functional from the playful hands of the designer
  4. Self-documenting at the code level is as simple as possible - it’s less and at the same time clearer to me
  5. Ease of embedding - at any time you can build in any place and immediately get advantages

And a lot of all the little things.

Principles


The ideology of the library is based on the following theses. If we take them as a basis, then everything is further understood easily:

As well as several technological theses that will lead through the wilds, when it is necessary to make a decision "how to do it"? So that does not contradict the following:

')
Most importantly, Jiant (javascript interface abstract notation) is more of a development philosophy than a set of tricks. If you develop adhering to this philosophy, then everything turns out easily and naturally.

View


We design

So, at first we design the interface on json, without going into implementation details. For example, just listening to the narrator (or customer) about the registration form: “Let the user enter a name and email, then press the register button and a window will appear to him that he is registered, which he will click on and get inside.”
We describe it on json, as we hear and we write.

var registration = { //  ,       views: { //  views     View registrationFormView: { //   nameInput: jiant.input, //    emailInput: jiant.input, //    registerCtl: jiant.ctl //  ,      }, successView: { //      continueCtl: jiant.ctl //   , ,     }, errorView: { //      errorMessage: jiant.label, //    disposeCtl: jiant.ctl //             } } }; 


How to understand all this? We read the code as follows: “our application consists of three views — a registration form, a success message, and an error message. The registration form contains two input fields and one control ... "and so on. jiant.input and jiant.ctl are for documentation purposes only. For example, you can write this and it will also work, but it will be less clear when reading:

 var registration = { views: { registrationFormView: { nameInput: 1, emailInput: 1, registerCtl: 1, }, successView: { continueCtl: 1 }, errorView: { errorMessage: 1, disposeCtl: 1 } } }; 


We realize

Now, when the interface is described in a highly abstract and as brief as possible - we implement the logic of the application with the interface and implement the interface itself in html code. As a result, getting MVC in the form of json-html-javascript. First, we implement the views themselves in html, according to the following rules:


Implementation of registrationFormView:
 <div id="_registrationFormView"> Your name: <input class="_nameInput"> <br> Your email: <input class="_emailInput"> <br> <button class="_registerCtl">Register</button> </div> 

What is the underscore before id and class name? Below it is explained.

Similarly, we implement successView:
  <div id="_successView">   ,    ! <button class="_continueCtl">Continue</button> </div> 

and errorView.

Embody an abstraction

So, we have an abstract interface definition. There is its implementation. How to connect them?
In the following way:
 $(function() { jiant.bindUi("_", registration, true); }); 


Is done.

The bindUi function accepts the first parameter prefix that is added to each abstract definition of a View or View element. In this case, it is underlined. If you pass an empty string, the names in json and identifiers-classes in html will be the same. I find it convenient to use an underscore to improve the readability of html code - you can immediately see the significant interface elements.
The second parameter is a variable containing the abstract definition of the application. jiant gets the views element from it and associates each view with its implementation.
The third parameter is to enable debug mode, which simplifies the search for errors and increases the amount of output to the console.

Magic

Here a little bit of magic begins. During bindUi, each View is searched from the interface definition by ID. Then the resulting jQuery wrapper object is attached to the definition variable. That is, after running bindUi, the variable registration.views.registrationFormView contains the result $ ("#_ registrationFormView"). Also, each item of the view is searched by class and filled, that is, registration.views.registrationFormView.registerCtl contains $ ("#_ registrationFormView"). Find ("._ registerCtl").

For each link not found - an error is reported to the console. And if the debugging mode is enabled - at the end an alert is issued with a list of all errors, so that the developer does not exactly lose sight of this.

At the output, we have an interface description object fully attached to real html elements. Which can now be used in code logic as follows.

We use

The easiest way is to write your own separate javascript file and register for the onUiBound event, for example:
 jiant.onUiBound(function($, app) { //     jQuery wrapper       var view = app.views.registrationFormView, errorView = app.views.errorView; //    view.registerCtl.click(function() { errorView.hide(); if (view.nameInput.val() == "") { errorView.errorMessage.html(" !"); errorView.show(); } else if (view.emailInput.val() == "") { errorView.errorMessage.html(" !"); errorView.show(); } else { view.hide(); app.views.successView.show(); } }); }); 


Ready logic. This is not felt when reading, but in a good IDE - 75% of this code is auto-completed, i.e. saved time on writing and reduced the likelihood of errors due to typos.

What else


Over time, in the process of using templates, EventBus, hash navigation, AJAX work with the server are added - all in the form of the most autocompliant-friendly and requiring minimal effort from the developer.
Example AJAX definitions:
 var app = { ajax: { getDataFromServer: function(id, callback) {} } } 

More from the developer, nothing is required - jiant itself implements the AJAX request code.

It remains to use:
  app.ajax.getDataFromServer(6345, function(data) { //do smth with data }); 


Who knows GWT - immediately see the full similarity with the Async service.

Farther


If this article comes out in print and is of interest, I’m ready to further describe the remaining functions (templates, AJAX, states and event bus). Project code on gihub: github.com/vecnas/jiant , site with description: sites.google.com/site/jiantscript/home

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


All Articles