13 759
правок
Изменения
Нет описания правки
</source>
== Фреймворки Обзор фреймворков @@ ==
* Клиентские фреймворки «старые»
=== «Старые» @@ ===
Заслуживают упоминания два:* jQuery(фиг сдохнет, а надо бы)* ExtJS(тоже фиг сдохнет)* Сдохли: Yahoo UI, PrototypeJS* По-моему, сдыхает: Dojo
=== «Новые» = jQuery @@ ====
''Если скриптота — рас***дяйство, то 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|На этом уже ''можно'' писать}} ==== Пример @@ ==== <div '''ng-controller="LoanCalculator"'''> <div> Дата выдачи: <input name="" type="text" '''ng-model="props.start"''' /><br /> Сумма: <input name="" type="text" '''ng-model="props.total"''' /><br /> Процент: <input name="" type="text" '''ng-model="props.percent"''' /><br /> Срок: <input name="" type="text" '''ng-model="props.months"''' /> месяцев<br /> Штраф за просрочку: <input name="" type="text" '''ng-model="props.fine"''' /><br /> Пеня % годовых на просрочку: <input name="" type="text" '''ng-model="props.penaltyPercent"''' /><br /> <input type="button" value="Рассчитать" '''ng-click="recalc()"''' /> <input type="button" value="Сбросить" '''ng-click="clear()"''' /> </div> <table '''ng-if="payments.length"''' border="0"> <tr> <th>Дата</th> <th>Сумма</th> <th>Комментарий</th> </tr> <tr '''ng-repeat="payment in payments"'''> <td><input name="" type="text" '''ng-model="payment.date" ng-change="clear_from($index+1)"''' /></td> <td><input name="" type="text" '''ng-model="payment.total" ng-change="clear_from($index+1)"''' /></td> <td>{{payment.text}}</td> </tr> <tr '''ng-if="clean"'''> <th>Всего</th> <td>{{sum}}</td> <td>{{outsums}}</td> </tr> </table> </div> === 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|⇒ Быстро и при этом гибко}} ==== Библиотеки для 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]]