Page 1
basis.jsproduction ready framework
1
Page 2
Обо мне
@smelukov
Работаю в Avito Делаю большое SPA
Преподаю JS Учу создавать веб-приложения
Люблю JS и жену Но больше жену
Популяризирую basis.js Верю, что basis.js захватит мир
Сергей Мелюков
2
Page 3
Когда я рассказываю про basis.js
‣ Зачем?! Есть же [X] ‣ basis.js - сложный, а [X] - простой
3
Page 4
Возможно, я не точно доносил смысл того, что такое basis.js и это
повлекло поспешные выводы
4
Page 5
Действительно ли можно просто взять любой фреймворк и сразу начать делать веб-приложения?
5
Page 6
Нет! Любой фреймворк требует
изучения и опыта использования
6
Page 7
Поговорим о том, какие возможности дает basis.js из
коробки
7
Page 8
План‣Компоненты ‣Источники данных ‣Локализация ‣ Трекинг событий ‣Инструменты разработки ‣Заключение
8
Page 9
‣Компоненты ‣Источники данных ‣Локализация ‣ Трекинг событий ‣Инструменты разработки ‣Заключение
9
Page 10
basis.js - это компонентный подход
10
Page 11
OK
имя
фамилия
отчество
Отмена
11
Page 12
new Node({ template: ..., binding: { firstName: ..., lastName: ..., }});
12
Page 13
new Node({ template: ..., binding: { firstName: ..., lastName: ... }});
13
Page 14
basis.js - это шаблоны без логики
14
Page 15
<li *ngFor="let item of items; let i = index; trackBy: trackByFn">...</li> <li template="ngFor let item of items; let i = index; trackBy: trackByFn">...</li>
if (todos.length) { main = ( <section className="main"> <input className="toggle-all" type="checkbox" onChange={this.toggleAll} checked={activeTodoCount === 0} /> <ul className="todo-list"> {todoItems} </ul> </section> );}
15
Page 16
Логика в JS, шаблон в XHTML
16
Page 17
<b:style src="./person.css"/><div class="person"> <div>Имя: {firstName}</div> <div>Фамилия: {lastName}</div> </div>
17
Page 18
basis.js - это изоляция стилей и модульный CSS
18
Page 19
<b:style src="./person.css"/><b:isolate/> <div class="person"> <div class="photo"> ... </div> <div class="info"> ... </div> </div>
<style> ... </style> <div class="i1__person"> <div class="i1__photo"> ...</div> <div class="i1__info"> ...</div> </div>
19
Page 20
‣Компоненты ‣Источники данных ‣Локализация ‣ Трекинг событий ‣Инструменты разработки ‣Заключение
20
Page 21
basis.js - это гибкое взаимодействие с источниками
данных
21
Page 22
Источником данных может быть объект, коллекция объектов или
другой компонент
22
Page 23
new Node({ template: ..., binding: { ... }, dataSource: ... });
23
Page 24
childNodes
Component
items
Dataset (коллекция)
‣ model ‣ model ‣ model ‣ model ‣ model ‣ model
component component component component component component
24
Page 25
Контролировать источник данных можно при помощи состояний
25
Page 26
‣ processing - в состоянии синхронизации ‣ deprecated - данные устарели ‣ ready - готов к работе ‣ error - ошибка
26
Page 27
Примеры использования?
Page 28
Показываем спиннер, пока загружаются данные
Page 29
Обновляем устаревшие данные
Page 30
basis.js - это автоматические источники данных (индексы,
фильтры, etc…)
30
Page 32
Выбранные друзья
items
Доступные друзья
items
‣ model ‣ model ‣ model???
32
Page 33
Исключим выбранных друзей из всех друзей и получим доступных
друзей
33
Page 34
allFriends = new Dataset();
favoriteFriends = new Dataset();availableFriends = new Subtract({ minuend: allFriends, subtrahend: favoriteFriends});
34
Page 35
allFriends = new Dataset();
favoriteFriends = new Dataset();availableFriends = new Subtract({ minuend: allFriends, subtrahend: favoriteFriends});
35
Page 36
allFriends = new Dataset();
favoriteFriends = new Dataset();availableFriends = new Subtract({ minuend: allFriends, subtrahend: favoriteFriends});
36
Page 37
Почему не for?
37
Page 38
Придется реализовать механизм отслеживания изменений
38
Page 39
Такой механизм уже встроен в наборы basis.js!
39
Page 40
allFriends = new Dataset();
favoriteFriends = new Dataset();availableFriends = new Subtract({ minuend: allFriends, subtrahend: favoriteFriends});
40
Page 41
А есть еще что-то, кроме Subtract?
41
Page 42
42
‣ Merge - объединение коллекций ‣ Filter - фильтрация элементов коллекции ‣ Slice - срез элементов коллекции ‣ Split - деление коллекции на подмножества ‣ etc…
Page 43
Для агрегации элементов коллекции используются индексы
43
Page 44
44
‣ Min - минимальное значение коллекции ‣ Max - максимальное значение коллекции ‣ Avg - среднее значение коллекции ‣ Sum - сумма элементов в коллекции ‣ etc…
Page 45
Манипуляция с данными, а не с DOM DOM - всего лишь отображение
45
Page 46
‣Компоненты ‣Источники данных ‣Локализация ‣ Трекинг событий ‣Инструменты разработки ‣Заключение
46
Page 47
basis.js - это удобные инструменты локализации
47
Page 48
Словарь - это JSON-файл
48
Page 49
{ "en-US": { "hello": "Hello!" }, "ru-RU": { "hello": "Привет!" }}
49
Page 50
{ "en-US": { "hello": "Hello!" }, "ru-RU": { "hello": "Привет!" } }
<div> {l10n:hello}</div>
50
Page 51
<div> Привет!</div>
51
Page 52
В словарях можно использовать биндинги и разметку
52
Page 53
new Node({ template: ... binding: { firstName: ..., lastName: ... }});
53
Page 54
{ "_meta": { "type": { "hello": "markup" } }, "ru-RU": { "hello": "Привет, <b>{firstName} {lastName}</b>" }}
Page 55
{ "_meta": { "type": { "hello": "markup" } }, "ru-RU": { "hello": "Привет, <b>{firstName} {lastName}</b>" }}
<div> {l10n:hello}</div>
55
Page 56
<div> Привет, <b>Иван Петров</b> </div>
56
Page 57
Грамматическое число поддерживается на уровне словаря
57
Page 58
new Node({ template: ... binding: { total: ... }});
58
Page 59
{ "_meta": { "type": { "offer": "plural" } }, "ru-RU": { "offer": [ "Всего {#} объявление", "Всего {#} объявления", "Всего {#} объявлений" ] }}
59
Page 60
{ "_meta": { "type": { "offer": "plural" } }, "ru-RU": { "offer": [ "Всего {#} объявление", "Всего {#} объявления", "Всего {#} объявлений" ] }}
<div> {l10n:offer.{total}} </div>
60
Page 61
<div> Всего 10 объявлений</div>
61
Page 62
‣Компоненты ‣Источники данных ‣Локализация ‣ Трекинг событий ‣Инструменты разработки ‣Заключение
62
Page 63
basis.js - это трекинг событий
63
Page 64
Разметим компоненты и шаблоны ролями
64
Page 65
<div b:role> <div> ... </div> <button b:role="ok">OK</button> <button b:role="cancel">Отмена</button> </div>
new Node({ template: ..., role: "popup"});
65
Page 66
<div role-marker="popup"> <div> ... </div> <button role-marker="popup/ok">OK</button> <button role-marker="popup/cancel">Отмена</button> </div>
66
Page 67
Создадим tracking-map и укажем за чем необходимо следить
67
Page 68
{ "popup/ok": { "click": { ... } }, "popup/cancel": { "click": { ... } }}
map.json
68
Page 69
{ "popup/ok": { "click": [ ... ] }, "popup/cancel": { "click": [ ... ] }}
map.json
69
Page 70
Соединяем воедино
70
Page 71
tracker.loadMap(require('./map.json'));tracker.attach(function(info) { // Google Analytics ga(info.data);});
71
Page 72
tracker.loadMap(require('./map.json'));tracker.attach(function(info) { // Google Analytics ga(info.data);});
72
Page 73
tracker.loadMap(require('./map.json'));tracker.attach(function(info) { // Google Analytics ga(info.data);});
73
Page 74
‣Компоненты ‣Источники данных ‣Локализация ‣ Трекинг событий ‣Инструменты разработки ‣Заключение
74
Page 75
basis.js - это удобные инструменты разработки
75
Page 76
Граф зависимостей - простое приложение
76
Page 77
Граф зависимостей - сложное приложение
77
Page 78
‣ выбраны услуги ‣достаточно средств ‣достаточно прав
78
Page 79
Почему кнопка неактивна?
79
Page 81
Более подробно в докладе Романа Дворнова http://bit.ly/2fr9vXO
81
Page 82
‣ Прошлый опыт ‣ Компоненты ‣ Источники данных ‣ Локализация ‣ Трекинг событий ‣ Инструменты разработки ‣ Заключение
82
Page 83
И все таки… Почему мне нужно
использовать basis.js?
83
Page 84
basis.js уже сейчас активно используется в production
84
Page 85
Попробуйте basis.js и сделайте свои выводы
85
Page 86
Как попробовать?
86
Page 87
‣ npm i -g basisjs-tools basis create app basis server
87
Page 88
‣ npm i -g basisjs-tools ‣ basis create app
basis server
88
Page 89
‣ npm i -g basisjs-tools ‣ basis create app ‣ basis server
89
Page 91
Отлично! А минусы тоже есть?
91
Page 92
‣ Документация ‣ Есть что улучшать ‣ Сообщество (есть gitter)
92
Page 93
Спасибо за внимание!
93