forked from shower/shower
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
286 lines (263 loc) · 10.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
<!DOCTYPE html>
<html lang="ru">
<head>
<title>Первое знакомство с Knockout.js</title>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="node_modules/shower-ribbon/styles/screen-4x3.css">
</head>
<body class="shower list">
<header class="caption">
<h1>Первое знакомство с Knockout.js</h1>
<p>Всё, что нужно, чтобы принять решение и начать использовать в реальной жизни</p>
</header>
<section class="slide" id="cover">
<h2>Старый добрый нокаут</h2>
<p>докладчик Черносов Денис</p>
<img src="pictures/cover.jpg" alt="" class="cover">
<!--
To apply styles to the certain slides
set slide ID to get needed elements
-->
<style>
#cover {
background-color: #e75c01;
}
#cover h2 {
margin:30px 0 0;
color:#FFF;
text-align:center;
font-size:70px;
}
#cover p {
margin:0;
text-align:center;
color:#FFF;
font-style:italic;
font-size:20px;
}
#cover p a {
color:#FFF;
}
#cover img {
top: 72%;
}
</style>
</section>
<section class="slide">
<h2>Введение, история появления</h2>
<ul>
<li>Первый релиз: 5 июля 2010 г.</li>
<li>Автор: Steve Sanderson (Microsoft). Лицензия MIT</li>
<li>Поддержка браузеров: IE 6+, Firefox 3.5+, Chrome, Opera, Safari (desktop/mobile)</li>
<li>Статистика использования на июнь 2016 года: <b>на 251 сайте из 10k наиболее популярных (2.5%)</b>, в целом < 0.1% <sup>*</sup></li>
</ul>
<p class="note"><sup>*</sup>Источник: http://trends.builtwith.com/javascript/KnockoutJS.</p>
</section>
<section class="slide">
<h2>Документация, сообщество, плагины</h2>
<ul>
<li>Живые примеры</li>
<li>Интерактивные руководства</li>
<li>Документация</li>
<li>Блоги: <a href="http://www.knockmeout.net/">www.knockmeout.net</a></li>
<li>API, форум</li>
</ul>
</section>
<section class="slide">
<h2>Ключевые концепции</h2>
<ul>
<li>Объекты, доступные для наблюдения (Observables) и отслеживание зависимостей</li>
<li>Декларативное связывание (Declarative bindings)</li>
<li>Шаблонизация (Templating)</li>
</ul>
</section>
<section class="slide">
<h2>Архитектура Model-View-ViewModel (MVVM)</h2>
<ul>
<li>Model - это ваши бизнес-данные</li>
<li>ViewModel - данные и логика представления. Переменные и функции для генерации шаблонов и обработки событий UI</li>
<li>View - это интерактивное UI-представление состояния ViewModel. Оно посылает команды во ViewModel и обновляется, когда обновляется ViewModel</li>
</ul>
</section>
<section class="slide">
<h2>Шаблон Наблюдатель (Observer)</h2>
<pre>
<code>var self = this;</code>
<code>self.name = <mark>ko.observable</mark>('Anonymous');</code>
<code>self.list = <mark>ko.observableArray</mark>(['a', 'b', 'c']);</code>
<code>var nameLogger = self.name.<mark>subscribe</mark>(function(newValue) {
console.log(newValue) ;
});</code>
<code>if (!debugMode) { nameLogger.<mark>dispose()</mark>; }</code>
</pre>
<p class="note">События и <b>beforeChange</b> и <b>change</b> не всегда отработают в паре</p>
</section>
<section class="slide">
<h2>Шаблон Наблюдатель (Observer)</h2>
<pre>
<code>self.total = <mark>ko.computed</mark>(function() {
return this.list().length;
}, self);</code>
<code>self.fullName = <mark>ko.pureComputed</mark>(function() {
return this.firstName() + " " + this.lastName();
}, self);</code>
</pre>
</section>
<section class="slide">
<h2>Расширения наблюдателей (ko.extenders)</h2>
<pre><code>ko.extenders.<mark>logChange</mark> = function(target, <mark class="important">option</mark>) {
target.subscribe(function(newValue) {
console.log(<mark class="important">option</mark> + ": " + newValue);
}); return target;
};</code></pre>
<hr />
<pre><code>this.firstName = ko.observable("Bob")
.extend({<mark>logChange</mark>: <mark class="important">"first name"</mark>});</code></pre>
</section>
<section class="slide">
<h2>Обвязки (Bindings)</h2>
<p class="note">ViewModel</p>
<pre><code>var myViewModel = { <mark class="important">personName</mark>: ko.observable('Bob') };
...
ko.applyBindings(myViewModel); <span class="comment">//Горошочек вари!</span></code></pre>
<hr />
<p class="note">View</p>
<pre><code>The name is <span <mark>data-bind</mark>="<mark>text</mark>: <mark class="important">personName</mark>"></span></code></pre>
</section>
<section class="slide">
<h2>Обвязки (Bindings)</h2>
<ul>
<li>visible, text, html, css, style, attr</li>
<li>foreach, if, ifnot, with, template, component</li>
<li>click, event, submit, enable, disable, value, textInput, hasFocus, checked, options, selectedOptions, uniqueName</li>
<li>...</li>
</ul>
</section>
<section class="slide">
<h2>Собственные обвязки (ko.bindingHandlers)</h2>
<pre><code>ko.bindingHandlers.<mark>popover</mark> = {
init: function (element) {
$(element).<mark class="important">popover</mark>({ placement: "right",
trigger: 'hover'});
}};</code></pre>
<pre><code><span data-bind="<mark>popover</mark>: true"
data-content="Some text"></span></code></pre>
</section>
<section class="slide">
<h2>Назад в будущее: почти как в JQuery, но гораздо лучше (Unobtrusive event handlers)</h2>
<ul>
<li>ko.dataFor(element)</li>
<li>ko.contextFor(element)</li>
</ul>
<pre><code>$(".container").on("click", ".remove", function() {
viewModel.items.remove(<mark>ko.dataFor(this)</mark>);
});</code></pre>
</section>
<section class="slide">
<h2 class="shout">Шаблоны и компоненты</h2>
</section>
<section class="slide">
<h2>Утилиты (ko.utils)</h2>
<ul class="double">
<li>unwrapObservable = unwrap</li>
<li>peekObservable</li>
<li>parseJson</li>
<li>stringifyJson</li>
<li>objectForEach</li>
<li>arrayForEach</li>
<li>arrayMap</li>
<li>arrayGetDistinctValues</li>
<li>other array*</li>
<li>extend</li>
<li>range</li>
<li><mark>postJson</mark></li>
<li>...</li>
</ul>
</section>
<section class="slide">
<h2>Горшочек не вари - отключаем автоматическое отслеживание зависимостей</h2>
<ul>
<li>observable.peek() vs observable()</li>
<li>ko.ignoreDependencies( callback, callbackTarget, callbackArgs );</li>
</ul>
</section>
<section class="slide">
<h2>Горшочек не гони - отложенные уведомления и прочие оптимизации</h2>
<ul>
<li>ko.options.deferUpdates = true</li>
<li>ko.observableArray().extend({ deferred: true })</li>
<li>ko.computed({ deferEvaluation: true })</li>
<li>ko.computed({ pure: true })</li>
<li>someObservableOrComputed.extend({ rateLimit: 500 })</li>
</ul>
</section>
<section class="slide">
<h2>Горшочек не хитри - обязательные уведомления</h2>
<ul>
<li>someComputed.extend({ notify: 'always' })</li>
</ul>
</section>
<section class="slide">
<h2>Миграция на KO в унаследованном проекте</h2>
<ul>
<li>Легко берёт на себя управление сколь угодно малыми частями UI</li>
<li>Поддерживает несколько View-ViewModel на одной странице, привязанные к разным DOM-элементам</li>
<li>Замечательно дружит с JQuery и его компонентами. </li>
<li>Не навязывает ничего, кроме базовых концепций</li>
<li>Легко дружится с другими библиотеками. Например: sammy.js (роутинг на стороне клиента)</li>
</ul>
</section>
<section class="slide">
<h2>Use cases</h2>
<ul>
<li>Таблицы и списки</li>
<li>Формы</li>
<li>Валидация, фильтрация, форматирование</li>
<li>Локализация</li>
<li>Сериализация/десериализация: плагин mapping</li>
<li>AJAX</li>
<li>Ненавязчивые обработчики событий: почти как в JQuery</li>
<li>Тесты</li>
</ul>
</section>
<section class="slide">
<h2>Продвинутые методики</h2>
<ul>
<li>Препроцессинг обвязок (ko.bindingHandlers.<name>.preprocess)
<ul>
<li>Значения по умолчанию</li>
<li>Парсеры выражений в обвязках</li>
</ul>
</li>
<li>
Препроцессинг узлов DOM (ko.bindingProvider.instance.preprocessNode)
<ul>
<li>Дополнительные манипуляции с DOM-элементами</li>
<li>Поддержка собственного синтаксиса виртуальных элементов разметки</li>
</ul>
</li>
</ul>
</section>
<section class="slide">
<h2>Внедрение с нуля. Управление зависимостями</h2>
<ul>
<li>Grunt</li>
<li>Bower</li>
<li>AMD + RequireJS</li>
</ul>
</section>
<section class="slide">
<h2 class="shout shrink">Вопросы?</h2>
</section>
<!--
To hide progress bar from entire presentation
just remove “progress” element.
-->
<div class="progress"></div>
<script src="node_modules/shower-core/shower.min.js"></script>
<!-- Copyright © 2015 Yours Truly, Famous Inc. -->
<!-- Photos by John Carey, fiftyfootshadows.net -->
</body>
</html>