📜 ⬆️ ⬇️

Introducing the right-angled, constructor of grids for angular2.



Today we want to talk about how we decided to repay the open source community and created the right-angled library. Just yesterday, we transferred it to beta status and decided to share this great news with the first co-habrasoobschestvom.

What makes right-angled


First of all, this library is designed to build grids (aka lists, aka tables) in applications on angular 2 .

In the second, this is a very advanced selection model. Working not necessarily in conjunction with grids. This is just a selection. Anything.
')
Another (not yet fully formed) idea is the declarative setting of component properties for:


without writing the code manually.

Free?


Yes, right-angled licensed under the MIT license. The source code of the library is available on github .

We also placed on github-pages a demo application detailing the capabilities of the library with live demos and code samples. If you suddenly want to look at the source code of the demo application, they are here .

Why did we create “another grid library”?


When we chose to work the existing libraries under angular 2, we came to the conclusion that they are too “heavy” and complex. For example, a simple grid template with a typical grid library for angular 2 looks like this:

<grid-component [dataSource]="data"> <grid-column-component fieldName="Id" title="Id"> </grid-column-component> <grid-column-component fieldName="Name" title="Name"> </grid-column-component> <grid-column-component field="Price" title="Price" width="230"> </grid-column-component> <grid-column-component field="IsDiscounted" title="Is Discounted" width="120"> <row-template let-dataItem> <input type="checkbox" [checked]="dataItem.IsDiscounted" /> </row-template> </grid-column-component> </grid-component> 

This template has too little HTML and too many “grids libraries”. Many components, many settings, too much to remember.

This complexity seemed unnecessary to us with a modern approach to development. And we decided to try to do something more lightweight and pleasant.

Also, the consequence of the first drawback is the second - the layout that these components generate.

Grid is a rather complicated control. And the HTML generated by such components does not always look good being built into the final application. Not to mention the fact that this HTML may just be frankly bad.

The opposite extreme is the universal markup, which takes into account all possible options, but such markup is not always quickly drawn and is always difficult to stylize. You can spend many hours on styling, and the grid will still look like “not native” in your design.

Simple styling, by the way, is one of the most important moments, since the “cloned” sites in the bootstrap style have not been satisfied with customers for a long time. And each new project is often a new, unique design.

Having understood all the above, we decided to create our own library, and lay down the following principles in it:

1. Minimum of components


The library must contain a minimum of components and be embedded in the layout of the final application, and not generate its own. The same applies to styles - right-angled does not contain any css and the appearance of your application is entirely yours.

Below is an example of a simple list template. As you can see, this is the usual layout using bootstrap (its use is not at all necessary, it is taken just for example) and quite a few custom directives.

 <table class="table table-striped" [rtList]="getData" #list="rtList"> <thead> <tr> <th>Id</th> <th>Name</th> <th>Price in USD</th> <th>Is Discounted</th> </tr> </thead> <tbody> <tr *ngFor="let item of list.items"> <td>{{item.Id}}</td> <td>{{item.Name}}</td> <td>{{item.Price}}</td> <td><input type="checkbox" [checked]="item.IsDiscounted" /></td> </tr> </tbody> </table> 

Such a template looks simple enough, since we didn’t add such concepts as “row”, “column”, “view template”, “editing template” and others so familiar to the grid libraries to our library. Such abstractions (and with them components) are often added to the grid libraries. But, in our opinion, they are redundant and introduce unnecessary complexity.

2. Simple functionality


So that the “minimum of components” did not turn into the “minimum of functional”, we completed the library with a set of functional services. The components of the library itself rely on them and the user can integrate them into their components using Dependency Injection in order to implement the desired behavior independently.

If you make the individual components lazily, then access to these services can be obtained directly in the template, referring to the directive hosts. There are four such directives in total - rtList with list functionality, rtSelectionArea with selection functionality and rt-buffered-pager components and rt-pager-pager components for working with paging.

For example, instead of a ready-made pager with a bunch of options, we were treated with primitive wrapper components and a couple of auxiliary directives. And they made a detailed example that helps the user of the library to implement their own full-featured pager.

Below you can see the code of the template list from the final example in the quick tour of our application. Added to it:


In this template, we just turn to the services described above in a “lazy” way - directly in the template.

The template turned out to be plump, but a lot of functionality was added. And this is still pretty clean, styled HTML, which in addition is very easy to break into compact and reusable components (in the demo application this is not done for ease of example).

  <form> <div class="row"> <div class="col-md-4 col-sm-6"> <div class="form-group"> <label>Airport name</label> <input type="text" class="form-control" [(ngModel)]="airportName" name="airportName" /> </div> </div> <div class="col-md-4 col-sm-6"> <div class="form-group"> <label>Country</label> <input type="text" class="form-control" [(ngModel)]="countryName" name="countryName" /> </div> </div> <div class="col-md-4 col-sm-6"> <div class="form-group"> <input (click)="list.loadData()" [disabled]="list.busy" type="submit" class="btn btn-load" title="Load data" /> <input (click)="list.cancelRequests()" [disabled]="list.ready" type="button" class="btn btn-cancel" title="Cancel loading" /> <button (click)="list.resetSettings()" [disabled]="list.busy" type="button" class="btn btn-reset" title="Reset settings"></button> </div> </div> </div> </form> <div class="table-responsive"> <table class="table table-striped" [rtList]="getAirports" #list="rtList" [loadOnInit]="false"> <thead> <tr> <th><span rtSort="iataCode">IATA</span></th> <th><span rtSort="name">Airport name</span></th> <th><span rtSort="countryName">Country</span></th> </tr> </thead> <tbody rtSelectionArea> <tr *ngFor="let airport of list.items" [rtSelectable]="airport"> <td>{{airport.iataCode}}</td> <td>{{airport.name}}</td> <td>{{airport.countryName}}</td> </tr> </tbody> <tfoot> <tr> <td colspan="3"> <rt-demo-paged-footer> </rt-demo-paged-footer> </td> </tr> </tfoot> </table> </div> 

Surely not everything in this template looks clear. But in order to keep the article compact, we did not copy the description of the functional from the demo application here, so all explanations can be viewed in it .

3. Minimum dependencies


right-angled does not depend on such libraries as bootstrap, jquery, jquery UI, etc. These libraries are certainly good and useful, but the decision on their use is better for the end user of the library. And when you implement grids, you can easily do without them.

The only dependency, in addition to angular, is the e2e4 library that we have written , which delivers abstract service-specific frameworks for the implementation of the entire functionality.

e2e4, in turn, has no dependencies at all. But, if you are working in a browser that does not support es6, then you will need some es6 polyfil. For example, es6 shim or core js . However, shim and so needed for angular work.

Further plan


Only yesterday we transferred the library to beta status, so there is still a lot of work. The immediate plans are as follows:

  1. Stabilize the library and bring it to release.
  2. Translate the demo application into English and compile full-fledged documentation with further library output to the world community.
  3. Refine the demo application by pulling out all the features of our library, since a couple of features are still hidden.

We also want to ask the community


If you notice a mistake or something seemed incomprehensible to you, please write to us about it. This is especially true demo applications. We are well aware that to write good, intelligible documentation, this is real skill, which we do not yet know perfectly.

In addition to creating an issue on github, you can contact the author of the article and the main library developer right here on Habré. You can also subscribe to twitter for a right-angled account in which we will publish news about our library.

We say goodbye to this. Thanks for attention :)

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


All Articles