Изменения

ECMAScript и все-все-все

8310 байтов добавлено, 23:46, 10 октября 2016
Нет описания правки
</source>
== Фреймворки Обзор фреймворков @@ ==
* Клиентские фреймворки «старые»
=== «Старые» @@ ===
Заслуживают упоминания два:* jQuery(фиг сдохнет, а надо бы)* ExtJS(тоже фиг сдохнет)* Сдохли: Yahoo UI, PrototypeJS* По-моему, сдыхает: Dojo
=== «Новые» = jQuery @@ ====
* React* AngularJS{{blue|«Меня зовут Мистер Свинья!»}}
''Если скриптота — рас***дяйство, то jQuery — {{red|ВЕРХ}} рас***дяйства'' Ибо РАСПОЛАГАЕТ к плохому коду:* Всё в кучу: объект-бог с кучей хелперов $ {{mag|и такие же модули}} {{gray|(например, DataTables)}}* <tt><nowiki>$.extend(), $.ajax(), $("<html>"), $(".class")</nowiki></tt>* Селекторы / операции над множествами: <tt><nowiki>$(".class").each(e => $(e).hide())</nowiki></tt>*: {{red|если элементов не найдётся, no problem, ничего не сдохнет}}* Страшные контроллеры, гвоздями прибитые к UI* Отсутствие возможностей оптимизации при динамической сборке UI*: {{gray|Пример — WikiEditor}} ==== ExtJS @@ ==== * Desktop-like фреймворк, {{green|умеет кучу всего}}* Фундаментально {{red|тормозноват}}* Со стилизацией большие трудности*: {{gray|Ну хоть тема в ExtJS >= 4 стала норм, можно смотреть без рвотных позывов}}* По моему опыту — писать на нём НЕ проще и НЕ быстрее, чем на HTML+JS* Data binding есть, но ограниченный — только свойств (а не иерархии) компонентов === «Новые» (компонентные) @@ === * Data binding*: <s>Knockout, Ember, Backbone</s>*: {{gray|упомянем для истории; неактуальны}}*: {{green|AngularJS 1, 2}}* Virtual DOM*: {{green|React}} И те, и другие — по сути, {{mag|решают задачу шаблонизации на JS}}. === AngularJS 1 @@ === * Dirty checking* Все биндинги 2-way* Поэтому медленный* Есть компоненты («директивы») и контроллеры* {{blue|На этом уже ''можно'' писать}} ==== Пример @@ ====  &lt;div '''ng-controller="LoanCalculator"'''&gt; &lt;div&gt; Дата выдачи: &lt;input name="" type="text" '''ng-model="props.start"''' /&gt;&lt;br /&gt; Сумма: &lt;input name="" type="text" '''ng-model="props.total"''' /&gt;&lt;br /&gt; Процент: &lt;input name="" type="text" '''ng-model="props.percent"''' /&gt;&lt;br /&gt; Срок: &lt;input name="" type="text" '''ng-model="props.months"''' /&gt; месяцев&lt;br /&gt; Штраф за просрочку: &lt;input name="" type="text" '''ng-model="props.fine"''' /&gt;&lt;br /&gt; Пеня % годовых на просрочку: &lt;input name="" type="text" '''ng-model="props.penaltyPercent"''' /&gt;&lt;br /&gt; &lt;input type="button" value="Рассчитать" '''ng-click="recalc()"''' /&gt; &lt;input type="button" value="Сбросить" '''ng-click="clear()"''' /&gt; &lt;/div&gt; &lt;table '''ng-if="payments.length"''' border="0"&gt; &lt;tr&gt; &lt;th&gt;Дата&lt;/th&gt; &lt;th&gt;Сумма&lt;/th&gt; &lt;th&gt;Комментарий&lt;/th&gt; &lt;/tr&gt; &lt;tr '''ng-repeat="payment in payments"'''&gt; &lt;td&gt;&lt;input name="" type="text" '''ng-model="payment.date" ng-change="clear_from($index+1)"''' /&gt;&lt;/td&gt; &lt;td&gt;&lt;input name="" type="text" '''ng-model="payment.total" ng-change="clear_from($index+1)"''' /&gt;&lt;/td&gt; &lt;td&gt;&#x7B;{payment.text}}&lt;/td&gt; &lt;/tr&gt; &lt;tr '''ng-if="clean"'''&gt; &lt;th&gt;Всего&lt;/th&gt; &lt;td&gt;&#x7B;{sum}}&lt;/td&gt; &lt;td&gt;&#x7B;{outsums}}&lt;/td&gt; &lt;/tr&gt; &lt;/table&gt; &lt;/div&gt; === Angular 2 @@ === * Пофиксили скорость, разделив 1-way и 2-way биндинги* Перешли на TypeScript ''{{gray|и всех агитируют}}''* Обновились в целом* {{green|Больше "искаропки"}}* {{red|Но зато тяжелее. Зачем-то тянет за собой RxJS…}} === React: почему я за React? @@ === * {{mag|JSX}}: на первый взгляд странно, на самом деле — круто и удобно!* '''Строго однонаправленный''' поток данных*: {{gray|(2-way binding - как чуть сложнее, так проблема)}}* {{green|Правильная компонентность}}*: Убирает все сомнения в том, MV-что у нас — MVVM, MVC, M-V-VC, M-V-VC-VM…*: Контроллер занимается тем, чем и должен: работой с данными* Легковесный, простой, изящный. Учится за 1 вечер. Не принуждает к дополнительным компонентам. ==== Почему JSX — круто? @@ ==== Даёт писать шаблоны прямо на JS! Удобно и безопасно. Например, цикл:* Ember: <nowiki>{{# each}}</nowiki>* Angular 1: ng-repeat* Angular 2: ngFor* Knockout: <nowiki>data-bind="foreach"</nowiki>* React: {{blue|ПРОСТО ИСПОЛЬЗУЙТЕ JS :)}} (обычный for или Array.map()) ==== JSX @@ ==== <source lang="javascript">var MessageInList = React.createClass({ msgClasses: { unread: 'unread', unseen: 'unseen', answered: 'replied', flagged: 'pinned', sent: 'sent' }, render: function() { var msg = this.props.msg; return <div data-i={this.props.i} className={'message'+ (msg.body_text || msg.body_html ? '' : ' unloaded')+ (msg.flags.map(c => (this.msgClasses[c] ? ' '+this.msgClasses[c] : '')).join(''))+ (this.props.selected ? ' selected' : '')+ (msg.thread && this.props.threads ? ' thread0' : '')} onMouseDown={this.props.onClick}>  <div className="icon" style={{ width: (20+10*(msg.level||0)), backgroundPosition: (10*(msg.level||0))+'px 7px' }}></div> <div className="subject" style={{ paddingLeft: (20+10*(msg.level||0)) }}>{msg.subject}</div> {msg.thread && this.props.threads ? <div className={'expand'+(msg.collapsed ? '' : ' collapse')}></div> : null} <div className="bullet"></div> <div className="from" style={{ left: (21+10*(msg.level||0)) }}> {(msg.props.sent ? 'To '+(msg.props.to[0][0]||msg.props.to[0][1]) : (msg.props.from ? msg.props.from[0]||msg.props.from[1] : ''))} </div> <div className="size">{Util.formatBytes(msg.size||0)}</div> <div className="attach" style={msg.props.attachments && msg.props.attachments.length ? null : { display: 'none' }}></div> <div className="time">{Util.formatDate(msg.time)}</div>  </div> }});</source> ==== JSX и Virtual DOM @@ ==== * Как применять изменения быстро?*: ''(DOM — относительно медленный)''* Храним {{mag|копию DOM}} в виде json* После render() сравниваем* Изменения применяем {{red|к реальному DOM}}: {{green|&rArr; Быстро и при этом гибко}} ==== Библиотеки для React @@ ==== * Flux* или Redux* react-router* react-router-redux* HTTP? superagent. === Как писать на React @@ === [https://facebook.github.io/react/docs/thinking-in-react.html Thinking in React]# Набросать (или взять у дизайнеров) HTML-макет# Выделить компоненты#: Помним, что компонент — ''единица рендера''# Сделать статическую версию на React, всё через props# Выделить состояние, определить владельца состояния#: Можно уже брать Flux/Redux#: Presentational vs Controller# Добавить изменения состояние === React Native @@ ===
[[Категория:VitaliPrivate]]