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:
- Code completion (autocomplete) - instead of string declarations.
- Complete interface abstraction and separation of logic and presentation
- 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
- Self-documenting at the code level is as simple as possible - it’s less and at the same time clearer to me
- 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:
- Any interface consists of a set of views (View, View?) - it is difficult to choose a word in Russian, since these are not widgets, but not screens. These are unique meaningful parts of the interface. The easiest way to select them is to simply listen to the customer’s story: here’s the “contact editing screen”, from here we go to the “users list” (there can be several View on the page at the same time).
- Each View contains a set of elements, such as “return button to list”, “user list container”, “user picture”. These items are identifiable within a single view.
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:
- What the user sees as a result on the screen is essentially the html code. What would be the best html draw? Only html itself. That is, when we need to show the user a certain interface - we simply put its html on the page and use it when necessary. Instead of generating through DOM, manipulating or concatenating strings on the fly (except in the simplest cases). It will also make life easier for the designer - he will simply design the html code.
- Repeating elements are generated by templates, which again is just html code on the page
')
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 = {
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:
- Each View corresponds to an html element with the corresponding id
- Each element of the View (nameInput, registerCtl) corresponds to the element html with the corresponding class, located inside the element of View
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) {
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) {
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