- PVSM.RU - https://www.pvsm.ru -
Сегодня хотим рассказать о том, как мы решили отдать долг open source сообществу и создали библиотеку right-angled [1]. Только вчера мы перевели ее в статус beta и решили поделиться этой отличной новостью с читателим c самым первым.
В первую очередь, данная библиотека предназначена для построения гридов (aka списков, aka таблиц) в приложениях на angular 2 [2].
Во вторую, это весьма продвинутая модель selection. Работающая не обязательно в связке с гридами. Это просто selection. Чего угодно.
Еще одной (пока не до конца оформившейся) идеей является декларативная настройка свойств компонентов для:
без написания кода вручную.
Да, right-angled распространяется по лицензии MIT. Исходный код библиотеки доступен на github [1].
Также мы разместили на github-pages демо-приложение [3], детально описывающее возможности библиотеки с живыми демо и примерами кода. Если вам вдруг захочется посмотреть на исходники демо-приложения, они здесь [4].
Когда мы выбирали для работы имеющиеся библиотеки гридов под angular 2, то пришли к выводу, что они слишком “тяжелые” и сложные. Например, шаблон простейшего грида с типичной библиотекой гридов для angular 2 выглядит примерно так:
<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>
В данном шаблоне слишком мало HTML и слишком много “библиотеки гридов”. Много компонентов, много настроек, слишком много того, что придется запомнить.
Эта сложность показалась нам излишней при современном подходе к разработке. И мы решили попробовать сделать что-то более легковесное и приятное.
Также, следствием первого недостатка является второй – верстка, которую генерируют подобные компоненты.
Грид – это достаточно сложный контрол. И HTML, генерируемый такими компонентами, не всегда выглядит хорошо будучи встроенным в конечное приложение. Не говоря уже о том, что этот HTML может быть просто откровенно плохим.
Обратной крайностью является универсальная разметка, которая учитывает все возможные варианты, но такая разметка не всегда быстро отрисовывается и всегда трудно стилизуется. Можно потратить многие часы на стилизацию, а грид все равно будет выглядеть в вашем дизайне как «не родной».
Простая стилизация, к слову, является одним из самых важных моментов, поскольку “клонированные” сайты в стиле bootstrap заказчиков уже давно не устраивают. И каждый новый проект – это нередко и новый, уникальный дизайн.
Осмыслив все выше сказанное, мы решили создать свою библиотеку, и заложить в нее следующие принципы:
Библиотека должна содержать минимум компонентов и встраиваться в верстку конечного приложения, а не генерировать свою. То же самое касается стилей — right-angled не содержит какого-либо css и внешний вид вашего приложения остается целиком за вами.
Ниже приведен пример шаблона простейшего списка. Как вы можете заметить, это обычная верстка с использованием bootstrap (его использование совсем не обязательно, он взят просто для примера) и совсем немного кастомных директив.
<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>
Такой шаблон выглядит достаточно простым, поскольку мы не стали добавлять в нашу библиотеку такие понятия как «строка», «столбец», «шаблон просмотра», «шаблон редактирования» и прочие, столь привычные для библиотек гридов. Подобные абстракции (а вместе с ними и компоненты) часто добавляются в библиотеки гридов. Но, на наш взгляд, они избыточны и вносят ненужную сложность.
Чтобы “минимум компонентов” не превратился в “минимум функционала”, мы укомплектовали библиотеку набором функциональных сервисов. На них опираются компоненты самой библиотеки и их же пользователь может внедрить в свои компоненты при помощи Dependency Injection, чтобы реализовать нужное поведение самостоятельно.
Если же делать отдельные компоненты лениво, то доступ к этим сервисам можно получить прямо в шаблоне, обращаясь к директивам-хостам. Всего таких директив четыре — rtList с функционалом списков, rtSelectionArea с функционалом работы с selection и компоненты rt-buffered-pager и rt-pager-pager для работы с paging.
Например, вместо готового pager-а с кучей опций, мы обошлись примитивными компонентами-обертками и парой вспомогательных директив. И составили детальный пример [5], помогающий пользователю библиотеки реализовать собственный полнофункциональный pager.
Ниже вы можете увидеть код шаблона списка из финального примера в quick tour [3] нашего приложения. В него добавлены:
В данном шаблоне мы как раз обращаемся к сервисам описанным выше «ленивым» способом — напрямую в шаблоне.
Шаблон получился пухлый, но ведь и функционала добавлено немало. И это по прежнему довольно-таки чистый, стилизуемый HTML, который вдобавок очень легко разбить на компактные и переиспользуемые компоненты (в демо-приложении этого не сделано для простоты восприятия примера).
<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" rtDemoSerializeToQueryString
(onListInit)="onListInit($event)">
<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" [class.selected]="rts.selected" [rtSelectable]="airport" #rts="rtSelectable">
<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>
Наверняка не все в этом шаблоне выглядит понятным. Но, чтобы сохранить статью компактной, мы не стали копировать сюда описание функционала из демо-приложения, поэтому все пояснения можно посмотреть в нем [3].
right-angled не зависит от таких библиотек, как bootstrap, jquery, jquery UI и т.п. Данные библиотеки, безусловно, хороши и полезны, но решение об их использовании лучше принимать конечному пользователю библиотеки. А при реализации гридов без них вполне можно обойтись.
Единственной зависимостью, помимо angular, является написанная нами же библиотека e2e4 [6], которая и поставляет абстрактные от конкретных presentation фреймворков сервиса для реализации всего функционала.
e2e4, в свою очередь, вообще не имеет зависимостей. Но, если вы работаете в браузере, не поддерживающем es6, то вам понадобится какой-либо es6 полифил. Например, es6 shim [7] или core js [8]. Впрочем, shim и так нужен для работы angular.
Только вчера мы перевели библиотеку в статус беты, поэтому работы еще очень много. Ближайшие планы следующие:
Если вы заметили ошибку или вам что-то показалось непонятным, пожалуйста, напишите нам об этом. Особенно это касается демо-приложения. Мы отлично понимаем, что написать хорошую, внятную документацию, это настоящее мастерство, которым мы пока не владеем в совершенстве.
Помимо создания issue на github, вы можете связаться с автором статьи и главным разработчиком библиотеки прямо здесь [9], на Хабре. Также вы можете подписаться в twitter на аккаунт right-angled [10], в котором мы будем публиковать новости о нашей библиотеке.
На этом прощаемся. Спасибо за внимание :)
Автор: EastBanc Technologies
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/211136
Ссылки в тексте:
[1] right-angled: https://github.com/eastbanctechru/right-angled
[2] angular 2: https://angular.io/
[3] демо-приложение: https://eastbanctechru.github.io/right-angled-demo/quick-tour
[4] они здесь: https://github.com/eastbanctechru/right-angled-demo
[5] детальный пример: https://eastbanctechru.github.io/right-angled-demo/paging-and-state#reusable-paged-pager
[6] e2e4: https://github.com/eastbanctechru/e2e4
[7] es6 shim: https://github.com/paulmillr/es6-shim
[8] core js: https://github.com/zloirock/core-js
[9] прямо здесь: https://habrahabr.ru/users/fshchudlo/
[10] right-angled: https://twitter.com/rightangledng2
[11] Источник: https://habrahabr.ru/post/315558/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.