Выбор JavaScript-фреймворка для вашего веб-приложения может быть невыносим. В настоящее время очень популярны Angular и React, и есть также выскочка, получающий много внимания в последнее время: VueJS. Кроме них, лишь эти несколько новичков.



Итак, как же нам выбрать? Список плюсов и минусов никогда не повредит. Проделаем это в стиле моей предыдущей статьи, “9 шагов: выбор технологического стэка для вашего веб-приложения”.


Прежде чем начнем — SPA или нет?


Сперва вы должны принять четкое решение, нужно ли вам одностраничное веб-приложение(SPA), или вы предпочли бы многостраничный подход. Больше на эту тему в моем посте “Одностраничные веб-приложения(SPA) против Многостраничных веб-приложений(MPA)”(скоро выйдет, следите за обновлениями в Twitter).


Участники сегодняшнего состязания: Angular, React and Vue


Сначала я хотел бы обсудить жизненный цикл и стратегические соображения. Затем мы перейдем к возможностям и идеям всех трех JavaScript-фреймворков. Наконец, мы придем к выводам.


Вопросы, которые мы сегодня рассмотрим:


  • Насколько зрелые эти фреймворки/библиотеки?
  • Будут ли эти фреймворки существовать еще какое-то время?
  • Насколько велики и полезны сообщества вокруг них?
  • Насколько легко найти разработчиков под каждый из этих фреймворков?
  • Каковы основные идеи этих фреймворков?
  • Насколько просто использовать эти фреймворки для небольших и крупных веб-приложений?
  • Какова кривая обучения для каждого из фреймворков?
  • Какую производительность вы ожидаете от этих фреймворков?
  • Где вы можете подробнее узнать, что у них под капотом?
  • Как начать разрабатывать с выбранным фреймворком?

На старт, внимание, марш!


Жизненный цикл и стратегические соображения



React vs. Angular vs. Vue


1.1 Немного истории


Angular — это JavaScript-фреймворк, основанный на TypeScript. Разработанный и поддерживаемый Google, он описывается как “Супергеройский JavaScript MVW фреймворк”. Angular(известный также как “Angular 2+”, “Angular 2” или “ng2”) — переписанный, по большей части несовместимый преемник AngularJS(известный как “Angular.js” или “AngularJS 1.x”). Хотя AngularJS(старый) был впервые выпущен в октябре 2010-го, он до сих пор получает багфиксы и т.д. Новый Angular(без JS) был представлен как версия №2 в сентябре 2016. Последний мажорный релиз — версия 4, так как версию 3 пропустили. Angular используется Google, Wix, weather.com, healthcare.gov и Forbes(в соответствии с madewithangular, stackshare и libscore.com).


React характеризуется как “JavaScript-библиотека для создания пользовательских интерфейсов”. Впервые выпущенный в марте 2013-го, React разработан и поддерживается Facebook-ом, который использует React-компоненты на нескольких страницах(однако, не являясь одностраничным веб-приложением). В соответствии с этой статьей Криса Кордла, React в Facebook применяется значительно шире, чем Angular в Google. React также используют в Airbnb, Uber, Netflix, Twitter, Pinterest, Reddit, Udemy, Wix, Paypal, Imgur, Feedly, Stripe, Tumblr, Walmart и других(в соотв. с Facebook, stackshare и libscore.com).


В данный момент Facebook работает над выпуском React Fiber. Это изменит React под капотом — в результате, рендеринг должен значительно ускориться — но обратная совместимость сохранится после изменений. В Facebook рассказывали об этих изменениях на их конференции для разработчиков в апреле 2017-го, также была опубликована неофициальная статья о новой архитектуре. Предположительно, React Fiber будет выпущен вместе с React 16.


Vue — один из самых быстроразвивающихся JS-фреймворков в 2016-м. Vue описывает себя как “Интуитивный, Быстрый и Интегрируемый MVVM для создания интерактивных интерфейсов”. Впервые он был выпущен в феврале 2014-го бывшим сотрудником Google Эваном Ю(кстати, Эван тогда написал интересный пост про маркетинговую деятельность и цифры в первую неделю после старта). Это был неплохой успех, особенно учитывая, что Vue привлекает столько внимания будучи театром одного актера, без поддержки крупной компании. На данный момент, у Эвана есть команда из дюжины основных разработчиков. В 2016 была выпущена вторая версия. Vue используют Alibaba, Baidu, Expedia, Nintendo, GitLab. Список более мелких проектов можно найти на madewithvuejs.com.


И Angular, и Vue доступны под лицензией MIT, в то время как React — под BSD3-license. Есть много обсуждений по поводу патентного файла. Джеймс Аид(бывший инженер Facebook) объясняет причины и историю, лежащую за этим файлом: Патент Facebook касается распространения их кода при сохранении возможности защитить себя от патентных исков. Файл патента обновлялся единожды и некоторые люди утверждают, что React можно использовать, если ваша компания не собирается подавать в суд на Facebook. Можете ознакомиться с обсуждением вокруг этого Github issue. Я не являюсь адвокатом, поэтому вы сами должны решить, создает ли лицензия React проблемы для вас или вашей компании. Есть еще много статей на эту тему: Дэннис Уолш пишет, почему вам не стоит бояться. Рауль Крипалани предостерегает от использования в стартапах, у него также есть обзор в формате “изложение мыслей”. Также существует недавнее оригинальное заявление от Facebook на эту тему: “Разъяснение лицензии React”.


1.2 Core development


Как было отмечено ранее, Angular и React поддерживаются и используются крупными компаниями. Facebook, Instagram и Whatsapp используют их на своих страницах. Google использует их во многих своих проектах: например, новый пользовательский интерфейс Adwords был реализован с помощью Angular и Dart. Опять же, Vue разрабатывается группой лиц, чья работа поддерживается через Patreon и другие средства спонсирования. Решайте сами, хорошо это или плохо. Маттиас Гёцке считает, что небольшая команда Vue — это плюс, потому что это ведет к более чистому коду / API, и меньшему оверинженерингу.


Посмотрим на статистику: на странице команды Angular перечислено 36 человек, у Vue — 16 человек, у React страницы команды нет. На GitHub-е у Angular больше 25 000 звезд и 463 контрибьютора, у React — больше 70 000 звезд и 1000 контрибьюторов, и у Vue почти 60 000 звезд и лишь 120 контрибьюторов. Можете также проверить страничку “Github Stars History for Angular, React and Vue”. Опять же, Vue, похоже, очень хорошо развивается. В соответствии с bestof.js, за последние три месяца Angular 2 получал в среднем 31 звезду в день, React — 74 звезды, Vue — 107 звезд.



A Github Stars History для Angular, React и Vue (Источник)


Апдейт: Спасибо Полу Хеншелю за то, что указал на npm trends. Они показывают количество скачиваний для данных npm-пакетов и даже полезнее, как чистый взгляд на звезды GitHub.



Количество скачиваний для заданных npm-пакетов в течение двух лет


1.3 Жизненный цикл на рынке


Angular, React и Vue сложно сравнить в Google Trends из-за их разнообразных имен и версий. Одним из способов получить приблизительные значения может быть поиск в категории “Internet & technologies”. Вот результат:



Ну, что ж. Vue до 2014 года не существовало — значит, тут что-то не так. La Vue по-французски — “вид”, “взгляд”, или “мнение”. Может быть, дело в этом. Сравнение “VueJS” с “Angular” или “React” несправедливо, так как у VueJS почти нет результатов, которые можно сравнить с остальными.


В таком случае, попробуем кое-что другое. Technology Radar от ThoughtWorks дает хорошее представление о том, как технологии эволюционируют в течение времени. Redux находится на стадии принятия(принятия в проектах!) и он был бесценен на ряде проектов ThoughtWorks. Vue.js на стадии испытаний(испытайте!). Его описывают, как легковесную и гибкую альтернативу Angular с более низкой кривой обучения. Angular 2 находится на стадии оценки — он успешно используется командами ThoughtWorks, но пока не имеет настоятельных рекомендаций.


В соответствии с последним опросом StackOverflow 2017, React любят 67% опрошенных разработчиков, а AngularJS — 52%. “Отсутствие интересу к продолжению разработки” регистрирует большие значения для AngularJS(48%) в сравнении с React(33%). Vue не входит в первую десятку ни в одном из случаев. Далее, есть опрос statejs.com, сравнивающий “front-end фреймворки”. Самые интересные факты: React и Angular обладают 100%-й известностью, Vue незнаком 23%-м опрошенных людей. Касательно “удовлетворенности”, React набрал 92% для варианта “использовал бы снова”, Vue — 89%, Angular 2 — только 65%.


Как насчет другого опроса об удовлетворенности пользователей? Эрик Элиотт запустил один в октябре 2016-го, чтобы оценить Angular 2 и React. Лишь 38% опрошенных людей использовали бы Angular 2 снова, в то время как 84% использовали бы снова React.


1.4 Долгосрочная поддержка и миграции


API React-а достаточно стабилен, как заявляет об этом Facebook в своих принципах проектирования. Существуют также скрипты, помогающие мигрировать с вашего текущего API на новый: попробуйте react-codemod. Миграции достаточно просты и здесь нет такой вещи(и необходимости в ней), как LTS версии. В этом посте на Reddit люди отмечают, что апгрейд на самом деле никогда не был проблемой. Команда React написала пост об их схеме версионирования. Когда они добавляют предупреждение об устаревании, они оставляют его для остальной части текущей релизной версии до того момента, пока поведение не будет изменено в следующей мажорной версии. Планов выпустить новую мажорную версию нет — v14 выпущена в октябре 2015-го, v15 опубликована в апреле 2016-го, а у v16 пока нет даты релиза. Обновление не должно стать проблемой, как недавно заметил один из основных разработчиков React.


Что касается Angular, есть пост о версионировании и релизах Angular начиная с релиза v2. Будет одно мажорное обновление каждые шесть месяцев и период устаревания(deprecation period), как минимум шесть месяцев(два мажорных релиза). Существуют экспериментальные API, помеченные в документации более коротким периодом устаревания. Официального анонса нет, но в соответствии с этой статьей, команда Angular анонсировала LTS версии начиная с Angular 4. Они будут поддерживаться как минимум год после следующего мажорного релиза. Это значит, что Angular 4 будет поддерживаться багфиксами и важными патчами как минимум до сентября 2018-го. В большинстве случаев, обновление со второй до четвертой версии Angular также просто, как обновление зависимостей Angular. Angular также предоставляет руководство с информацией о том, какие понадобятся изменения в дальнейшем.


Процесс обновления с Vue 1.x до 2.0 должен быть простым для небольшого приложения — команда разработчиков утверждает, что 90% API осталось без изменений. Имеется приятный инструмент для диагностики обновления и помощи во время миграции, работающий из консоли. Один из разработчиков отметил, что обновление с v1 до v2 до сих пор не приносит особого удовольствия на больших приложениях. К сожалению, roadmap-а для следующего мажорного релиза или информации о планах создания LTS версий нет.


Еще кое-что: Angular — это цельный фреймворк, предлагающий кучу вещей в комплекте. React гибче, чем Angular, и вы, вероятно, столкнетесь с использованием более независимых, неустаканенных, быстроразвивающихся библиотек — это означает, что вам придется самостоятельно заботиться о соответствующих обновлениях и миграциях. Это может нанести вред, если определенные пакеты больше не поддерживаются или если какой-то другой пакет в определенный момент становится стандартом де-факто.


1.5 Кадровые ресурсы и найм


Если у вас есть HTML-разработчики, которые не хотят углубляться в JavaScript, вам лучше выбрать Angular или Vue. React повлечет за собой увеличение количества JavaScript-а(позже мы поговорим об этом).


У вас есть дизайнеры, работающие в непосредственной близости с кодом? Пользователь “pier25” отмечает в своем Reddit-посте, что выбирать React имеет смысл, если вы работаете в Facebook, где каждый разработчик — супергерой. В реальном мире, вы не всегда найдете дизайнера, способного модифицировать JSX — по существу, работать с HTML-шаблонами будет намного проще.


Хорошая новость относительно Angular это то, что новый Angular 2-разработчик из другой компании сможет быстро ознакомиться со всеми необходимыми соглашениями. Каждый проект на React отличается в плане архитектурных решений и разработчикам нужно будет знакомиться с настройками конкретного проекта.


Angular также хорош, если у вас есть разработчики с ООП-бэкграундом или те, кто не любят JavaScript. Чтобы заострить на этом внимание, цитата Манеша Чанда:


“Я не JavaScript-девелопер. Мой бэкграунд — создание крупномасштабных корпоративных систем с использованием “настоящих” платформ для разработки ПО. Я начинал в 1997-м, разрабатывая приложения на C, C++, Pascal, Ada и Fortran. (...) Я могу точно сказать, что JavaScript для меня просто белиберда. Будучи MVP в Microsoft и экспертом, я хорошо понимаю TypeScript. Я также не рассматриваю Facebook, как компанию-разработчика ПО. Однако, Google и Microsoft уже крупнейшие инноваторы в этой сфере. Я чувствую себя более комфортно, работая с продуктом, у которого есть хорошая поддержка от Google или Microsoft. Также (...) с моим бэкграундом, я знаю, что у Microsoft даже большие планы для TypeScript”

Ну… Видимо, я должен упомянуть, что Манеш Чанд является региональным директором в Microsoft.


Сравнение React, Angular и Vue


2.1 Компоненты


Все обсуждаемые фреймворки основаны на компонентах. Компонент получает что-то на вход и после внутренних вычислений возвращает отрендеренный шаблон UI(область входа / выхода с сайта или элемент списка to-do) на выходе. Определенные компоненты должно быть легко переиспользовать на веб-странице или в других компонентах. Например, у вас мог бы быть компонент сетки(состоящий из шапки и нескольких компонентов для рядов) с разнообразными свойствами(колонки, информация о шапке, data rows, и т.д.) и возможностью переиспользования этого компонента с разными данными на другой странице. Вот всеобъемлющая статья о компонентах на тот случай, если вам захочется изучить их получше.


И React, и Vue превосходно подходят для работы с “тупыми” компонентами: небольшие функции, не имеющие состояния, которые получают что-то на вход и возвращают элементы на выходе.


2.2 TypeScript vs ES6 vs. ES5


React фокусируется на использовании JavaScript ES6. Vue использует JavaScript ES5 либо ES6.


Angular зависит от TypeScript. Это дает большую консистентность в примерах и в опенсорсных проектах(примеры React можно найти в ES5 или в ES6). Это также вводит такие понятия, как декораторы или статическая типизация. Статическая типизация полезна для инструментов для анализа кода, типа автоматического рефакторинга, перехода к определению и т.д. — они должны уменьшить количество багов в приложении, хотя консенсус по поводу их использования, определенно, не достигнут. Эрик Элиот не согласен с этим в своей статье “Шокирующий секрет статических типов”. Дэниэл С Вонг говорит, что использование статических типов не вредит и что хорошо иметь разработку через тестирование(TDD) и статическую типизацию одновременно.


Вам, вероятно, следует знать о том, что вы можете использовать Flow, чтобы включить проверку типов в React. Это инструмент для статической проверки типов, разработанный Facebook для JavaScript. Flow также можно интегрировать в VueJS.


Если вы пишете код на TypeScript, вы уже не пишете стандартный JavaScript. Несмотря на рост, у TypeScript до сих пор крошечное число пользователей, по сравнению со всем языком JavaScript. Один из рисков может заключаться в том, что вы будете двигаться в неверном направлении, поскольку TypeScript может — хотя и вряд ли — исчезнуть со временем. Помимо того, TypeScript создает приличный оверхед на проектах(на обучение) — можете больше почитать об этом в Сравнении Angular 2 и React от Эрика Элиотта.


Апдейт: Джеймс Рейвенскрофт написал к этой статье комментарий о том, что у TypeScript первоклассная поддержка JSX — компоненты можно легко проверить на соответствие типу. Так что, если вам нравится TypeScript и вы хотите использовать React, это не должно быть проблемой.


2.3 Шаблоны — JSX или HTML


React нарушает устоявшиеся best practices. Десятилетиями разработчики пытались разделить шаблоны и встроенную джаваскриптовую логику, но в JSX они опять перемешаны. Может быть, это звучит ужасно, но вам следует послушать речь Питера Ханта “React: Переосмысление best practices”(от октября 2013-го). Он указывает на то, что разделение шаблонов и логики — это просто разделение технологий, а не ответственности. Вы должны создавать компоненты вместо шаблонов. Компоненты переиспользуемы, интегрируемы и удобны для unit-тестирования.


JSX — это опциональный препроцессор с HTML-подобным синтаксисом, который затем компилируется в JavaScript. Отсюда некоторые странности — например, вам нужно использовать className вместо class, потому что последний является в JavaScript зарезервированным ключевым словом. JSX — большое преимущество для разработки, так как у вас все будет в одном и том же месте, а также быстрее будут работать автокомплит и проверки на стадии компиляции. Когда вы допускаете ошибку в JSX, React не компилирует код и выводит номер строки, в которой допущена ошибка. Angular 2 тихо падает в рантайме(возможно, этот аргумент некорректен, если вы пользуетесь AOT с Angular).


JSX подразумевает, что все в React = JavaScript — он используется и для JSX-шаблонов, и для логики. Кори Хаус указывает в своей статье от января 2016-го: “Angular 2 продолжает внедрять ‘JS’ в HTML. React внедряет ‘HTML’ в JS”. Это хорошо, потому что JavaScript мощнее, чем HTML.


Шаблоны в Angular представляют собой усовершенствованный HTML со специальным языком Angular(штуки, вроде ngIf или ngFor). В то время, как React требует знания JavaScript, Angular заставляет вас учить специфичный для Angular синтаксис.


Vue предлагает “однофайловые компоненты”. Это похоже на компромисс относительно разделения ответственности — шаблоны, скрипты и стили в одном файле, но в трех различных, упорядоченных секциях. Это значит, что вы получаете подсветку синтаксиса, поддержку CSS и возможность легко использовать препроцессоры типа Jade или SCSS. Я прочитал в других статьях, что JSX проще дебажить, потому что Vue не показывает синтаксические ошибки в HTML. Это не так, поскольку Vue конвертирует HTML в render-функции — поэтому ошибки показываются без проблем(Спасибо Винициусу Рейзу за комментарий и поправки!).


Примечание: Если вам нравится задумка с JSX и вам хочется использовать его в Vue, вы можете использовать babel-plugin-transform-vue-jsx.


2.4 Фреймворки против библиотек


Angular — больше фреймворк, чем библиотека, так как предоставляет убедительные предложения о том, как ваше приложение должно быть структурировано, а также имеет больше функционала из коробки. Angular — это “цельное решение” — включены “батарейки” и вам предоставляется возможность удобного старта. Вам не нужно проводить анализ библиотек, решать вопрос с роутингом и т.п. — вы можете просто начать работать.


React и Vue, с другой стороны, универсально гибки. Их библиотеки можно совмещать с любого рода пакетами(их достаточно много для React в npm, но у Vue пакетов меньше, так как он еще достаточно молод). Используя React, вы можете даже заменить саму библиотеку на ее API-совместимую альтернативу, такую как Inferno. С большей гибкостью, однако, появляется большая ответственность — для React не существует правил и и ограничительных рекомендаций. Каждый проект требует принятия решения относительно его архитектуры, и все может легко пойти не так, как планировалось.


С другой стороны, Angular поставляется с запутанным клубком систем для сборки, бойлерплейтов, линтеров и других пожирателей времени, с которыми придется иметь дело. Это верно и для React в случае использования стартер-китов или бойлерплейтов. Конечно, они очень полезны, React работает из коробки, и это, может быть для вас способ его изучить. Иногда разнообразие инструментов, необходимых для работы в JavaScript-окружении называют “усталостью от JavaScript”. Вот статья Эрика Клеммонса, который сказал следующее:


По-прежнему существует множество инструментов, к которым вы не привыкли, в момент когда вы начинаете работать с фреймворком. Они генерируются, но возможно многие разработчики не понимают, что происходит у них под капотом, либо требуется много времени, чтобы это понять.

Vue кажется самым чистым и легким из трех фреймворков. У GitLab есть пост о принятии решения в пользу Vue.js(октябрь 2016-го):


Vue.js прекрасно поставляется отлично сбалансированным в плане того, что он может сделать для вас и того, что вам нужно делать самостоятельно. (...) Vue.js всегда находится в пределах досягаемости; прочная, но гибкая сетка готова помочь сохранить эффективность вашего программирования и свести связанные с DOM страдания к минимуму.

Им нравится простота и легкость использования — исходный код очень читабелен и документация или внешние библиотеки не нужны. Все достаточно просто. Vue.js “не делает далекоидущих предположений о большей части чего-либо”. Имеется также подкаст о решении GitLab.


Другой пост о переходе на Vue от Pixeljets. React “был большим шагом вперед для мира JS в плане state-awareness, и он показал множеству людей реальное функциональное программирование хорошим, практичным способом”. Одним из серьезных минусов React по сравнению с Vue является проблема разбиения компонентов на более мелкие компоненты из-за ограничений JSX. Вот цитата из статьи:


Для меня и моей команды важна читабельность кода, но также крайне важно то, чтобы написание кода приносило удовольствие. Нет ничего приятного в том, чтобы создать 6 компонентов, если вы разрабатываете простенький виджет-калькулятор. Во многих ситуациях это также плохо в плане поддержки, модификаций или визуальной переработки какого-то виджета, так как вам надо перемещаться по множеству файлов/функций и по-отдельности проверять каждый маленький кусочек HTML. Опять же, я не предлагаю писать монолиты — я предлагаю использовать в повседневной разработке компоненты вместо микрокомпонентов.

На Hacker news и Reddit есть интересные дискуссии об этом посте — в наличии аргументы от недовольных и дальнейших сторонников Vue.


2.5 Управление состоянием и связывание данных


Разрабатывать UI сложно, так как состояния присутствуют везде — данные меняются с течением времени, что влечет за собой увеличение сложности. Определенные способы работы с состоянием оказывают большую помощь, когда приложение разрастается и становится более сложным. Для небольших приложений это может быть перебор, и что-то типа Vanilla JS было бы достаточно.


Как это работает? Компоненты описывают UI в определенный момент времени. Когда данные изменяются, фреймворк перерисовывает UI-компонент целиком — отображаемые данные всегда актуальны. Мы может назвать эту идею “UI как функция”.


React часто работает в паре с Redux. Redux описывает себя в трех фундаментальных принципах:


  • Единственный источник правды
  • Состояние доступно только для чтения
  • Изменения делаются с помощью чистых функций

Другими словами: состояние приложения целиком находится в дереве объектов внутри единого хранилища. Это помогает отлаживать приложение и кое-какая функциональность становится проще для реализации. Состояние в read-only режиме и может быть изменено только через “экшены”, чтобы избежать состояния гонки(также полезно для отладки). “Редьюсеры” пишутся, чтобы указать, как “экшены” могут трансформировать состояние.


Большая часть туториалов и бойлерплейтов включают в себя Redux, но вы можете использовать React без него(или вам может быть вообще не нужен Redux в вашем проекте). Redux добавляет сложность и достаточно серьезные ограничения для вашего кода. Если вы изучаете React, вам стоит подумать об изучении чистого React перед тем, как вы перейдете к Redux. Вам определенно стоит прочесть “Вам может быть не нужен Redux” Дэна Абрамова.


Некоторые разработчики предлагают использовать Mobx вместо Redux. Можете думать о нем, как о “автоматическом Redux”, который упрощает использование и понимание с самого начала. Если хотите посмотреть, вам стоит начать с введения. Вы можете также почитать это полезное сравнение Redux и MobX от Робина. Тот же автор также предлагает информацию о переходе с Redux на MobX. Этот список полезен, если вы хотите проверить другие Flux-библиотеки. И, если вы пришли из мира MVC, вы захотите прочесть статью “Философия Redux (если вы уже знаете MVC)” Михаила Левковского.


Vue можно использовать с Redux, но он предлагает Vuex как свое собственное решение.


Большое отличие между React и Angular — одно- или двустороннее связывание. Двустороннее связывание в Angular меняет модель состояния, когда элемент пользовательского интерфейса(к примеру, поле ввода) обновляется. React идет только одним путем: сначала обновляет модель и затем отрисовывает элемент. Подход Angular чище в коде и проще для реализации разработчиком. Подход React позволяет получить лучшее понимание о том, что происходит с данными, потому что поток данных течет лишь в одном направлении(это делает отладку проще).


Оба подхода имеют плюсы и минусы. Вам нужно понять эти идеи и определить, влияют ли они на ваше решение о выборе фреймворка. И статья “Двустороннее связывание: Angular 2 и React”, и этот вопрос на StackOverflow предоставляют хорошие объяснения. Здесь вы можете найти интерактивные примеры кода(возрастом в 3 года, только для Angular 1 и React). Последнее, но тем не менее важное: Vue поддерживает и одностороннее, и двустороннее связывание(одностороннее по-умолчанию).


Если хотите почитать больше, имеется длинная статья о различных типах состояния и управлении состоянием в Angular-приложениях(от Виктора Савкина).


2.6 Другие концепции программирования


Angular включает в себя dependency injection, паттерн, в котором один объект(сервис) предоставляет зависимости другому объекту(клиенту). Это дает большую гибкость и более чистый код. Статья “Понять dependency injection” в деталях объясняет эту идею.


Паттерн Модель-Вид-Контроллер(MVC) делит проект на три части — модель, вид и контроллер. У Angular, как у MVC-фреймворка, имеется поддержка MVC из коробки. У React есть лишь V — что будет M и C нужно решить вам самим.


2.7 Гибкость и переход к микросервисам


Вы можете работать с React или Vue просто добавляя JavaScript-библиотеку к исходникам. Это невозможно с Angular, потому что он использует TypeScript.


Мы все больше движемся в сторону микросервисов и микроприложений. React и Vue предоставляют вам полный контроль над размером приложения, позволяя включить только те вещи, которые действительно нужны. Они дают больше гибкости при переходе от SPA к микросервисам, используя части бывшего приложения. Angular лучше подходит для SPA, так как для использования в микросервисах он, вероятно, слишком раздут.


Как отмечает Кори Хаус:


JavaScript быстро развивается, и React позволяет вам заменять небольшие фрагменты вашего приложения более подходящими библиотеками вместо того, чтобы ждать и надеяться на то, что ваш фреймворк обновят. Философия маленьких, интегрируемых, узкоспециализированных инструментов никогда не выйдет из моды.

Некоторые люди также используют React для не-SPA вебсайтов(например, для сложных форм или мастеров). Даже Facebook использует React не для главной страницы, а, скорее, для определенных страниц и возможностей.


2.8 Размер и производительность


Обратная сторона функциональности: Angular довольно-таки раздут. Размер сжатого gzip-ом файла — 143кб, по сравнению с 23кб Vue и 43кб React.


И у React, и у Vue есть Virtual DOM, который должен увеличивать производительность. Если вам интересно, можете почитать об отличиях между Virtual DOM и DOM, а также о реальных преимуществах Virtual DOM в React. Один из авторов Virtual DOM также отвечает на вопросы, связанные с производительностью на StackOverflow.


Чтобы проверить производительность, я посмотрел великолепный js-framework-benchmark. Вы можете сами скачать и запустить его или посмотреть на интерактивную таблицу с результатами. Перед тем, как проверить результаты, вам нужно знать, что фреймворки обманывают бенчмарки — такие замеры производительности не должны быть основой принятия решений.



Производительность Angular, React и Vue (Источник)



Выделение памяти в Мб (Источник)


Чтобы подытожить: у Vue прекрасная производительность и лучшее распределение памяти, но все фреймворки действительно довольно рядом друг с другом, по сравнению с особенно медленными или особенно быстрыми фреймворками(типа Inferno). Еще раз: тесты производительности следует рассматривать как побочные данные, не для вынесения вердикта.


2.9 Тестирование


Facebook использует Jest, чтобы тестировать свой код на React. Здесь есть сравнение Jest и Mocha, и есть статья о том, как использовать Enzyme с Mocha. Enzyme — библиотека для тестирования, написанная на JavaScript, используемая Airbnb(в сочетании с Jest, Karma и другими тест-раннерами). Если вы хотите почитать побольше, имеются старые статьи про тестирование в React(здесь и здесь).


Далее, существует Jasmine, как тестовый фреймворк для Angular 2. В статье Эрика Элиотта говорится о том, что Jasmine “приводит к миллионам способов написания тестов и утверждений, нуждающихся в тщательном прочтении каждого из них, чтобы понять, что он делает”. Вывод также раздут и труден для чтения. Есть несколько информативных статей про интеграцию Angular 2 с Karma и Mocha. Также есть старое видео(от 2015-го) о тестовых стратегиях в Angular 2.


У Vue есть недостатки в тестировании, но Эван написал в своем превью от 2017-го, что команда планирует поработать над этим. Они рекомендуют использовать Karma. Vue работает с Jest, также есть тестовая утилита avoriaz.


2.10 Универсальные и нативные приложения


Универсальные приложения внедряются в веб, на десктопы, а также в мир нативных приложений.


И React, и Angular поддерживают нативную разработку. У Angular есть NativeScript(при поддержке Telerik) для нативных приложений и Ionic Framework для гибридных приложений. С React вы можете попробовать react-native-renderer, чтобы разрабатывать кроссплатформенные приложения для iOS или Android, или react-native для нативных приложений. Большое число приложений(включая Facebook; за подробностями на Showcase) сделаны с помощью react-native.


JavaScript-фреймворки рендерят страницы на клиенте. Это плохо для воспринимаемой производительности, пользовательского опыта в целом и SEO. Серверный рендеринг — это плюс. У всех трет фреймворков имеются библиотеки, чтобы помочь с этим. Для React это next.js, у Vue есть nuxt.js, и у Angular есть… Angular Universal.


2.11 Кривая обучения


У Angular, определенно, крутая кривая обучения. Он обладает всеобъемлющей документацией, но иногда это может вас расстраивать, потому что ряд вещей сложнее, чем кажется. Даже если вы глубоко понимаете JavaScript, вам нужно изучить, что происходит под капотом фреймворка. Вначале установка магическая, предлагает большое число встроенных пакетов и кода. Это можно рассматривать, как минус из-за большой, сразу существующей экосистемы, которую вам нужно со временем изучить. С другой стороны, это может и хорошо в определенных ситуациях, поскольку многие решения уже приняты. С React вам, скорее всего, придется принять множество внушительных решений относительно использования third-party библиотек. Существует 16 различных flux-пакетов для управления состоянием, которые можно выбрать для React.


Vue довольно прост для изучения. Компании переходят на Vue из-за того, что он кажется значительно более простым для начинающих разработчиков. Тут вы сможете почитать, как некто описывает переезд своей команды с Angular на Vue. По информации от другого пользователя, приложение на React в его компании было таким сложным, что новые разработчики не поспевали за сложностью кода. С Vue разрыв между младшим и старшим разработчиком сокращается, и они могут взаимодействовать проще и с меньшим количеством багов, проблем и времени на разработку.


Некоторые люди утверждают, что то, что они сделали на React было бы написано лучше с использованием Vue. Если вы — неопытный JavaScript разработчик — или в последние 10 лет работали в основном с jQuery — вам стоит подумать об использовании Vue. Сдвиг парадигмы более выражен при переходе на React. Vue выглядит больше как чистый JavaScript в тоже время привнося некоторые новые идеи: компоненты, событийная модель и однонаправленный data-flow. Также у него небольшой размер.


Тем временем, у Angular и React свой собственный подход к вещам. Они могут мешать вам, потому что вам нужно приспосабливаться под них, чтобы заставить их работать. Это может быть вредно из-за меньшей гибкости и крутой кривой обучения. Это также может быть и полезно, поскольку вас заставляют изучать правильные подходы в процессе изучения технологии. С Vue вы можете работать в стиле старомодного JavaScript. Это может быть проще вначале, но может стать проблемой в долгосрочной перспективе, если все сделать не верно.


Когда речь заходит об отладке, плюс React и Vue в меньшем количестве магии. Охота на баги проще, потому что есть лишь несколько мест, куда нужно смотреть, и у стектрейсов лучше видны отличия между собственным кодом и исходниками библиотеки. Работающие с React сообщают, что им никогда не требовалось читать исходный код библиотеки. Однако, отлаживая ваш код вашего приложения на Angular, вам часто нужно отлаживать внутренности Angular, чтобы понять лежащую в его основе модель. С другой стороны, сообщения об ошибках должны стать более чистыми и информативными начиная с Angular 4.


2.12 Под капотом Angular, React и Vue


Хотите проверить исходники самостоятельно? Хотите увидеть, как все складывается?


Возможно, вам стоит сначала проверить вот эти GitHub-репозитории: React(github.com/facebook/react), Angular(github.com/angular/angular) и Vue(github.com/vuejs/vue).


Как выглядит синтаксис? ValueCoders сравнивают синтаксис Angular, React и Vue.


Хорошо бы также увидеть все на продакшене — вместе с исходным кодом, на котором все основано. На TodoMVC есть список из десятков вариантов одного и того же Todo-приложения, написанного на различных JavaScript-фреймворках — можете сравнить решения на Angular, React и Vue. RealWorld разрабатывает реальное приложение(клон Medium) и у них есть готовые решения для Angular(4+) и React(с Redux). Для Vue работа в процессе.


Также есть некоторые реальные приложения, на которые вы можете посмотреть. Решения на базе React:



Приложения на Angular:



А также решения на Vue:



Заключение


Выберите фреймворк сейчас


И React, и Angular, и Vue достаточно круты, и никого из них нельзя поставить сильно выше остальных. Доверьтесь своему нутру. Эта последний кусочек развлекательного цинизма может помочь вам принять решение:


Грязный маленький секрет — “современная JavaScript-разработка” не имеет ничего общего с созданием веб-сайтов — это создание пакетов, которые могут использоваться людьми, создающими библиотеки, которые могут использоваться людьми, создающими фреймворки, которым люди, пишущие туториалы и ведущие курсы могут обучать. Не уверен, что кто-то действительно что-то создает для настоящих пользователей.

Это преувеличение, конечно, но в нем возможно есть доля правды. Да, в экосистеме JavaScript есть много лишнего шума. Может быть, вы найдете множество более привлекательных альтернатив во время ваших поисков — постарайтесь не быть ослепленным новейшим блестящим фреймворком.


Что я должен выбрать?


  • Если вы работаете в Google: Angular
  • Если вы любите TypeScript: Angular(или React)
  • Если вам нужно руководство, структура и рука помощи: Angular
  • Если вы работаете в Facebook: React
  • Если вам нравится гибкость: React
  • Если вы любите большие экосистемы: React
  • Если вам нравится выбирать из десятков пакетов: React
  • Если вы любиле JS и подход “все-есть-JavaScript”: React
  • Если вам нравится действительно чистый код: Vue
  • Если вы хотите простейшая кривую обучения: Vue
  • Если вы хотите самый легковесный фреймворк: Vue
  • Если вам хочется разделения ответственности в пределах одного файла: Vue
  • Если вы работаете один или в небольшой команде: Vue(или React)
  • Если ваше приложение имеет тенденцию разрастаться: Angular(или React)
  • Если вы хотите иметь большой пул девелоперов: Angular или React
  • Если вы работаете с дизайнерами и вам нужны чистые HTML-файлы: Angular или Vue
  • Если вам нравится Vue, но пугает ограниченная экосистема: React
  • Если вы не можете решить, изучите сначала React, затем Vue, затем Angular

Итак, вы приняли решение?



Дааа, вы его приняли!


Отлично! Читайте о том, как начать разрабатывать с Angular, React или Vue (скоро, подписывайтесь на меня в Twitter для обновлений).


Дополнительные ресурсы


React JS, Angular & Vue JS?—?Quickstart & Comparison (восьмичасовое введение и сравнение трех фреймворков)
Angular vs. React (vs. Vue)?—?the DEAL breaker (короткое, но превосходное сравнение от Доминика Т)
Angular 2 vs. React?—?the ultimate dance off (неплохое сравнение от Эрика Элиотта)
React vs. Angular vs. Ember vs. Vue.js (сравнение трех фреймворков в форме заметок от Гекана Сари)
React vs. Angular (понятное сравнение двух фреймворков)
Can Vue fight for the Throne with React? (приятное сравнение с большим количеством примеров кода)
10 reasons, why I moved from Angular to React (еще одно неплохое сравнение от Робина Вируча)
All JavaScript frameworks are terrible (большая заметка обо всех основных фреймворках от Мэтта Берджесса)

Комментарии (193)


  1. raveclassic
    18.09.2017 23:58
    +2

    Понеслась!


    1. Synoptic Автор
      19.09.2017 00:06
      +3

      В статье, походу, Vue вчехляют.


  1. Hazrat
    19.09.2017 00:13
    +9

    Вы что не понимаете? Джикверю всех их победил еще в 2006 году


    1. VovanZ
      19.09.2017 13:14
      +4

      image


  1. RomanPokrovskij
    19.09.2017 00:52

    Мне не хватает головы понять как изменятся реакт и ангулар с широкой поддержкой Shadow DOM и HTML templates броузерами. Angular поддерживает Shadow Dom но непонятно как с HTML templates. Если кто-то добавит свои соображения по этому пункту к статье — буду благодарен.


    1. Synoptic Автор
      19.09.2017 00:56

      HTML темплейты скорее всего скоро задепрекейтят в пользу JS-импортов. См. примеру это, а они чуть ли не известнейшая команда, широко использовавшая эту фичу.

      Как изменится Angular уже и так видно, включаешь флаг — получаешь нативную инкапсуляцию(пока толком не работает). React с его ультракостылями типа CSS-in-JS вроде не особо-то пока и стремиться дружить с веб-компонентами.


      1. Synoptic Автор
        19.09.2017 02:12

        Речь про HTML imports, конечно. HTML template почти везде работает и какой-то особой погоды не делает.


      1. RomanPokrovskij
        19.09.2017 02:17
        -1

        Вижу что Polymer задеприкейтил External stylesheets в компонентах, но это не тоже самое что HTML templates и мнение что JSимпорты могут заменить HTML templates — не вполне убедительно (статический html все же кажется непоколебимым столпом). Если я правильно Вас понял.

        Но мнение — что Shadow Dom и HTML Template могут устареть быстрее react звучит убедительно. Спасибо.


        1. Synoptic Автор
          19.09.2017 02:30

          Не совсем, там речь не про стайлшиты, а про HTML Imports, это когда <link rel="import" href="my-tag.html">. А уже в «my-tag.html» могли быть и стайлшиты и что угодно.

          Так вот похоже, так делать будет нельзя, придется импортировать HTML-темплейты в JavaScipt-модули тамошними импортами. Все бы ничего, но нативно сделать это сейчас невозможно, в том то и прикол HTML Import-ов — автоматический парсинг HTML при импорте. Но есть надежда на фичу импорта HTML в JS как DocumentFragment, типа как в вебпак, но нативно.

          До остального, Shadow DOM вряд ли устареет, остальное думаю тоже в том или ином виде доделают. Просто это небыстро, но никто и не спешит.


    1. PerlPower
      19.09.2017 00:58

      Мои соображения таковы, что к моменту поддержки указанных технологий в браузерах выйдет такое количество новых JS фреймворков, что анугляр с реактом будут сметены с повестки дня, и таким образом проблема поддержки в них чего либо будет решена.


  1. justboris
    19.09.2017 01:53
    +1

    Основная мысль — в конце статьи:


    И React, и Angular, и Vue достаточно круты, и никто из них нельзя поставить сильно выше остальных.

    Можно выбрать любой, но как именно? Обычно в моей работе это решалось так:


    1. Уже написан какой-то код, продолжаем писать на чем досталось
    2. Знаем хорошо технологию, берем ее, чтобы получить предсказуемые сроки и качество
    3. Намечается маленький проект — пробуем что-то новое, все равно не сложно будет переписать


    1. Synoptic Автор
      19.09.2017 02:04
      +9

      По моему опыту(3,5 года с различными SPA), такие выводы:

      • На чем писать без разницы, но лучше на том, за что платят и чтобы удовлетворяло начальным требованиям(сразу сужает круг, особенно кроссбраузерность)
      • Если и платят, и выбор есть, выбирать то, что лучше знаешь/больше нравится(мало кто знает на хорошем уровне несколько фреймворков, еще сильнее сужаем круг)
      • Проблемы будут хоть с jQuery-лапшой, хоть с космическими технологиями, точно также будешь сидеть писать код и править баги. Где-то чуть дольше, где-то чуть меньше,
        но по сути компонентный подход вырисовывается все равно.
      • Если маленький проект или самому побаловаться, брать то, что не пробовал. Запилил даже маленький проект — повысил свою цену на рынке за счет знания еще одного инструмента.

      Так что похоже на ваши.


      1. JekaMas
        20.09.2017 11:34
        +1

        Прекрасный пример Resume Driven Development!


        1. Synoptic Автор
          20.09.2017 12:17
          +1

          Прекрасный пример совмещения приятного с полезным.


  1. dom1n1k
    19.09.2017 04:48
    +4

    Если вы не можете решить, изучите сначала React, затем Vue, затем Angular
    А мне кажется, лучше изучать именно в хронологическом порядке — A, R, V. Не обязательно супер-глубоко, но хотя бы в общих чертах. Тогда на третьем шаге станет понятно:
    а) как шло развитие идеи;
    б) сколько шелухи отбрасывает Vue и насколько он прозрачнее.
    Как в анекдоте про козла в квартире — сначала нужно создать себе трудности, потом избавиться от них и почувствовать счастье.


  1. x07
    19.09.2017 08:48
    +1

    <цитата>Вы можете работать с React или Vue просто добавляя JavaScript-библиотеку к исходникам. Это невозможно с Angular, потому что он использует TypeScript.</цитата> Вам стоит лучше изучить ts и angular прежде чем делать такие заявления.


  1. alexs0ff
    19.09.2017 09:06
    -2

    Еще один пункт в пользу выбора Angular. Я пришел с backend, конкретно с .NET. Typescript+Angular самые близкие ко мне по привычной идеологии.


    1. Imrahil
      19.09.2017 11:55
      +1

      вообще не ощутил сложности ни с А ни с R. Vue не пробовал) мне хватает этих двух головняков)
      з.ы.
      Работая одновременно с back и front+back (R+Node или A+Node) почему-то больше понравилось всетаки работа с R =)) Видимо мозг переключается с одного на другое и ему легче, нед однотипности во всем)


    1. VolCh
      19.09.2017 22:31

      Хм, а у меня ровно наоборот впечатление. Реакт — тупо шаблон без всякой магии.


      1. indestructable
        21.09.2017 12:58

        И именно этим он хорош!


  1. lega
    19.09.2017 11:30

    Перед тем, как проверить результаты, вам нужно знать, что фреймворки обманывают бенчмарки
    И vue тут тоже отличился, без читинга он бы попал в нижнуюю половину списка (хотя там видимо многие читирят), но как минимум был бы ниже (медленее) ангуляра 2+.


    1. TimTowdy
      19.09.2017 12:28

      А можно поподробнее, чем именно отличился?


      1. lega
        19.09.2017 15:13

        Например когда другие фреймворки делают «click» биндинг на каждую строку, строк там где-то до 11к, семпл с vue — хитрят, делают один биндинг (сверху), что значительно экономит время (и память).
        Впрочем тоже самое можно сделать и для других фреймворков, но это какбы срезать путь по лесу, вместо того чтобы бежать по трассе.

        Это то что на поверхности, если копнуть глубже, думаю можно ещё что-нибудь найти, выше есть ссылка на статью о хаках некоторых фреймворков, так же я находил «хак» в ангуляре 2 альфа версии где вместо удаления строк они вставляют их обратно на второй интерации, хотя это спорный пункт — можно считать просто оптимизацией.


        1. TimTowdy
          19.09.2017 15:42
          +1

          Так и делегацию обработки событий родителю ведь тоже можно отнести к оптимизации. Это ведь не специально ради бенчмарков делается, а как раз для реальной оптимизации. Т.е. это не читинг, а реально полезная фича: код «среднестатистического» разработчика работает быстрее.


          1. lega
            19.09.2017 18:04

            Это ведь не специально ради бенчмарков
            Это не в фреймворке, а в бенчмарке сделано. Чтобы повыше позицию занять.

            Если такую «оптимизацию» считать валидной, то тогда добавте $mol в тест с его lazy списками, и он порвет всех и даже нативный JS в 10 раз*.


            1. vintage
              20.09.2017 05:44
              +1

              А что плохого в подобных оптимизациях, если они происходят на уровне фреймворка, а не прикладного кода?


              1. lega
                20.09.2017 09:34

                Конекретно lazy список — совсем другой компонент, нужен другой подход (врапер, спец. разметка), он имеет некоторые ограничения и отличия, по сравнению с обычным списком, его нужно в тест ленивых списков, а не в этот. Тем более большинство веб-приложений это не просто списки.

                если они происходят на уровне фреймворка
                Тогда хорошо, но заточка заложенная в фреймворк под конкретный тест выглядит некрасиво.


                1. vintage
                  20.09.2017 12:02

                  Конекретно lazy список — совсем другой компонент

                  Это не "lazy" список, а "вертикальный лэйаут", который может содержать элементы любых типов. Применяется всякий раз, когда надо расположить элементы вертикально (даже если всего 2 элемента, как в $mol_expander). Есть ещё "горизонтальный лэйаут с переносом" и прочие. Бонусом к ним идёт учёт видимой области при рендеринге, так что в них можно выводить произвольное число элементов, не боясь, что страница станет рендериться минуту.


                  нужен другой подход (врапер, спец. разметка)

                  Более чем стандартный для фреймворка подход, без "врапперов" и "спецразметок".


                  он имеет некоторые ограничения

                  Если речь про "браузерный поиск по странице", который не работает с неотрендеренными данными, то это ограничение всего фреймворка, который поощряет (и упрощает) использование внутристраничного поиска, который в подавляющем большинстве случаев работает лучше и который всё-равно необходим в случае больших объёмов данных и разбиения его на страницы.


                  и отличия

                  Возможное подёргивание скроллбара при дорендеривании опять же не особенность конкретного компонента, а компромис на уровне фреймворка. Все компоненты предоставляют свои минимальные размеры, а $mol_scroll учитывает их, задавая высоту скроллящейся области.


                  его нужно в тест ленивых списков

                  Если для пользователя не видно разницы (в случае todomvc — точно не видно), для разработчика не вино разницы (кроме небольших опциональных хинтов, уточняющих размеры, чтобы скроллбар не дёргался), то к чему эта дискриминация на основании внутренней оптимизации?


                  Тем более большинство веб-приложений это не просто списки.

                  Вот смотрите, огромная статья, содержащая параграфы, заголовки, таблицы, картинки, исходные коды. Открывается мгновенно, потому что рендерится лениво.


                  Тогда хорошо, но заточка заложенная в фреймворк под конкретный тест выглядит некрасиво.

                  Конкретный тест должен отражать реальный юзкейс, иначе грош цена такому тесту.


                  1. lega
                    20.09.2017 14:36

                    Вот смотрите, огромная статья, содержащая параграфы
                    Если честно, то скролл ведет себя не по человеческий не только при скроле вниз (если тащить скрол мышкой), но и вверх (зачем удалять уже отрендеренные итемы?)

                    то к чему эта дискриминация на основании внутренней оптимизации?
                    Тест создан, чтобы можно было прикинуть/сравнить производительность на будущих проектах, и вероятнее всего это будет не просто список.
                    Тест тестирует список, потому что это простейший способ создать «нагрузку/объем», поэтому урезание этого объема будет отражать неверные затраты, т.к. с отложенным отображением вы можете сократить список на 95%, когда реальные приложения можно «урезать» только на 5%*. Т.е. вы скрывате как фрейморк работает с большим кол-вом html-элементов.

                    Конкретный тест должен отражать реальный юзкейс, иначе грош цена такому тесту.
                    Согласен, но имеем что имеем, и многие на него ориентируются.


                    1. vintage
                      20.09.2017 16:18
                      -1

                      Если честно, то скролл ведет себя не по человеческий не только при скроле вниз (если тащить скрол мышкой)

                      Такова цена ленивости. Не сильно большая как по мне. В основном его таскают пальцем/колёсиком/тачпадом. Да и если курсором таскать — не такое уж прям сильное неудобство. Кроме того, основной сценарий — постепенное пролистывание, а не мотание взад-вперёд.


                      зачем удалять уже отрендеренные итемы?

                      Чем меньше единовременно на странице элементов, тем быстрее браузер с ней работает (reflow, layout size, styling, animations, memory usage).


                      реальные приложения можно «урезать» только на 5%

                      Моя практика говорит об обратном. Приведёте пример тяжёлого приложения, которое можно урезать лишь на 5%. Ну вот даже то приложение для чтения статей позволяет урезать гораздо больше. Тут даже важно не на сколько урезать, а асимптотика. Логарифмическая против линейной. В идеале — рендерить только то, что попадает в видимую область и больше ничего. Ленивый рендеринг $mol очень близок к этому идеалу на старте, когда все ползунки скроллинга наверху. Собственно, когда данных столько, что они все помещаются на экран, то все фреймворки достаточно быстры, чтобы пользователь не замечал тормозов (ну кроме совсем отбитых, конечно). Ну вот, если в todomvc бенчмарке поставить 10 задач, влезающих в экран, то все фреймворки дают 60-100мс (ну кроме тормозного Реакта, да, который даёт от 120 :-)), что неотличимо на глаз, да и вообще соразмерно с погрешностью. Но уже при 100 задачах ситуация резко меняется: $mol почти не замедлился выдавая 250мс, а остальные просели на порядок выдавая 500мс в лучшем случае (внезапно, Knockout), что уже является заметным пользователю подтормаживанием. "Быстрые" Реакты так вообще за 1000мс перевалили.


                      1. lega
                        20.09.2017 17:00

                        Чем меньше единовременно на странице элементов, тем быстрее браузер с ней работает
                        Тогда в добавок можно удалять блоки сверху, оставляя пустышки того же размера.

                        Приведёте пример тяжёлого приложения, которое можно урезать лишь на 5%.
                        У нас в компании большое веб-приложение, везде пагинаторы, вкладки и т.п., скролы не желательны т.к. это не «веб страничка с текстом» — желательно что-бы приложение помещалось в экран.

                        Только в одном проекте мне нужна была ленивая загрузка «строк», делается в 5-10* строк кода — просто определяю что скрол добежал до конца — добрасываю ещё 10-20 элементов в массив.

                        В одном проекте нужна была ленивая загрузка блоков, по несколько блоков в ряд, все блоки разной высоты, должны были красиво подстраиваться (менять позицию) что-бы лента была краисвая (без дыр), но на это $mol из коробки не способен.


                        1. vintage
                          20.09.2017 17:51

                          Тогда в добавок можно удалять блоки сверху, оставляя пустышки того же размера.

                          К сожалению тут есть сложности. Если меняется ширина контейнера или состояние скрытых сверху блоков, то пустышки не знают на сколько надо изменяться в размерах. В результате при скроллинге вверх будут неприятные скачки при замене пустышек на реальные блоки. Но я экспериментирую сейчас с бесконечной в обе стороны лентой, в которую можно было бы подкладывать/удалять блоки с обеих сторон без скачков. С кроссбраузерностью, к сожалению, пока беда.


                          У нас в компании большое веб-приложение, везде пагинаторы, вкладки и т.п., скролы не желательны

                          Пагинаторы не от хорошей жизни придуманы. Зачем они, если можно проскроллить?


                          Только в одном проекте мне нужна была ленивая загрузка «строк», делается в 5-10* строк кода

                          Добавьте иерархию и зашьётесь с отладкой. Может оказаться, что на 3 уровне глубины у вас окажется 100500 элементов.


                          В одном проекте нужна была ленивая загрузка блоков, по несколько блоков в ряд, все блоки разной высоты, должны были красиво подстраиваться (менять позицию) что-бы лента была краисвая (без дыр), но на это $mol из коробки не способен.

                          Ну, опишите подробней задачу, может и запилим стандартный компонент на это дело. У нас пока для этого есть лишь $mol_row.


                          1. lega
                            20.09.2017 20:36

                            Но я экспериментирую сейчас с бесконечной в обе стороны лентой
                            Отображать только «видимое» +120% от вьюпорта сверху снизу для плавного скроллинга, и независимый скрол с равномерной шкалой (1 ед. скрола = 1 элемент массива любой высоты)

                            Пагинаторы не от хорошей жизни придуманы.
                            Чтобы не вываливать весь список, и высота приложения была не большая. Вон гугл-поиск, gmail и др. используют пагинацию вместо автоподгрузки.

                            Ну, опишите подробней задачу
                            Это было в очень старом проекте, сейчас нет смысла тратить на это время.


                            1. vintage
                              20.09.2017 21:24

                              независимый скрол

                              Он будет отставать от прокрутки, ибо асинхронный.


                              1 ед. скрола = 1 элемент массива любой высоты

                              Тогда при наличии разновысотных блоков будет меняться скорость прокрутки.


                              У меня идея с изменением flex-direction при прокрутке вверх/вниз. Крутим вниз — дорендериваем вниз. Крутим вверх — дорендериваем вверх. Ну и оцениваем высоту скроллящейся области по контенту, как сейчас. То есть пригодно может быть и для вполне ограниченного списка.


                              Вон гугл-поиск, gmail и др. используют пагинацию вместо автоподгрузки.

                              Ну не осилили, бывает. УткаУткаПошла и Я.Почта, например, осилили.


                              Это было в очень старом проекте, сейчас нет смысла тратить на это время.

                              Ну может пригодится ещё.


                              1. lega
                                20.09.2017 23:15

                                Ну может пригодится ещё.
                                Пример тут, блоки разной высоты и автоподгрузка.


                                1. vintage
                                  21.09.2017 08:44

                                  Понял о чём вы. На мой взгляд такую раскладку сложнее воспринимать, так как человеку приходится бегать слева-направо прескакивая колонки. В результате он глазами будет попадать либо на то, что уже отсмотрел, либо будет что-то пропускать перескакивая не туда. Ну и в целом смотрится хаотично. Если привести размеры карточек к одному размеру в строке — получится и опрятней и удобней.


                                  Впрочем, реализовать такую раскладку тривиально:


                                  Создаём колонки в виде экземпляров $mol_list:


                                  Galery $mol_row
                                      items <= cols /
                                  -
                                  Col!index $mol_list
                                      rows <= col_items!index /

                                  Балансируем на них карточки:


                                  col_items( index : number ) {
                                      const items = this.items()
                                      const col_items = [] as typeof items
                                      const col_count = this.col_count()
                                      for( let index = index % col_count ; index < items.length ; index += col_count ) {
                                          col_items.push( this.Card( index ) )
                                      }
                                      return col_items
                                  }


  1. rockon404
    19.09.2017 11:55
    +1

    Заглядывая в будущее делаю выводы, что оно точно не за комбайнами «все в одном» вроде Angular. Фронтэнд сталкивается с проблемами, решает их и многие решения становятся в последствии прекрасными opensource проектами которые становятся для многих де-факто стандартами. В экосистеме вокруг этих проектов так-же рождается множество прекрасных решений для тех или иных задач. Для меня это Webpack, React, Redux, Redux Saga, Styled Components, ESLint, Flow, так как эти вещи позволяют делать работу быстро, эффективно, масштабируемо и понятно, при этом оставляя свободу в организации архитектуры под особенности тех или иных проектов, порог входа для новых разработчиков совсем не высок, а рефакторинг и миграции в целом безболезненны. Писать огромный комбайн покрывающий максимальное количество разных по сути задач, на мой взгляд, большая ошибка, с кучей вытекающих проблем с дальнейшей поддержкой развитием, как самих фреймворков, так и написанных на них проектов. Будущее там куда идет opensource сообщество, ведь оно пытается решить конкретные задачи наилучшим способом.


    1. alexs0ff
      19.09.2017 12:01

      >>громный комбайн покрывающий максимальное количество разных по сути задач
      .NET и Java. QT говорят об обратном
      Фреймворки очень востребованы, чем велосипедоделание.


      1. justboris
        19.09.2017 12:34

        Успешное существование Electron как бы намекает, что и в desktop-разработке есть спрос на более гибкие решения.


        Только с производительностью проблемы, поэтому либо скорость разработки, либо скорость работы


        1. alexs0ff
          19.09.2017 12:46

          >>Electron
          Сколько ему лет?
          Вот когда перевалит за 2-3 десяток, как в случае с JAVA или .NET, тогда и поговорим:)


          1. justboris
            19.09.2017 12:55

            Причем здесь возраст технологии?


            Я его привел как пример альтернативы монолитным UI-фреймворкам. Если бы всех устраивал QT и ко, Electron не появился бы в принципе.


            1. alexs0ff
              19.09.2017 12:57
              +1

              >>Если бы всех устраивал QT
              Видимо они в нем нашли «фатальный недостаток»
              >>Electron не появился бы в принципе
              А так если серьезно, за 10 лет, я столько повидал библиотек по работе с desctopом, но выжили лишь только единицы. Поэтому судить о необходимости того или иного фреймворка можно только после испытанию временем


              1. justboris
                19.09.2017 12:59

                И этим фатальным недостатком является сложная кастомизация монолитного UI, о чем и сказано в первом комменте треда.


                1. alexs0ff
                  19.09.2017 13:03
                  +2

                  >>сложная кастомизация монолитного UI
                  Вот уж не знаю, QML мне всегда больше нравился чем реакты и ангулары. Жалко его в ВЭБе нельзя применять


                  1. Semmaz
                    19.09.2017 18:21

                    Отчего же нельзя? QmlWeb


                1. impwx
                  19.09.2017 17:46
                  +1

                  Фатальным недостатком является то, что нужно писать код на чём-то кроме JS.


      1. rockon404
        19.09.2017 13:04

        Я имел ввиду частный случай фронтенда, странно, что вы не уловили этого из моего комментария. Безусловно для решения задач бэкенда в больших и средних проектах в большинстве случаев лучше и даже нужно использовать фреймворки. Но фронтэнд это совсем другая песня и другой круг задач. В комментарии выше вы писали, что пришли во фронт с бэкенда и ваш выбор в пользу Angular понятен. Я сам fullstack с бэкграундом Java и Ruby. Когда я думал куда уходить с морально устаревшего Backbone, я какое-то время писал на Angular и даже на Angular2, но поработав в проектах на React я больше никогда к нему не вернусь. Свою точку зрения о проблемах таких комбайнов, я в двух словах изложил выше. Советую вам познакомиться с другими технологиями(React, Vue, Redux, о самой архитектуре Flux, CSS in JS) и почитать о мотивации их создания. Опенсорс, на мой взгляд, движется в правильном направлении. Столкнувшись с большинством задач и проблем в больших проектах во фронтэнде, я думаю, вы и сами со мной согласитесь.


        1. alexs0ff
          19.09.2017 13:12

          >>проблем в больших проектах во фронтэнде
          Большая проблема frontenda это то, что слишком много игроков. Отсюда просто зверинец часть которого погибает/обновляется/устаревает. В этом вся и проблема, я получил огромный опыт на бэкэнде и он мне говорит, что как раз технологии «все в коробке» живут дольше всего (.NET, JAVA, QT), а остальное шелуха и меняется очень часто.
          Другой отличительной особенностью долгоживущих проектов являются именно майнтейнеры. Google +Microsoft (Angular+typescript) уж я думаю куда более живучие, чем Facebook.


          1. rockon404
            19.09.2017 14:07
            +1

            То что вы подразумеваете под «большой проблемой» фронтенда, вовсе не проблема, а лишь следствие его быстрого развития. И чтобы не делать неверных выводов вам лучше изучить историю этого «зверинца» решений: предпосылки к появлению, мотивацию, недостатки. Тогда и придет понимание почему одни канули в небытие, а на их место пришли другие, какие проблемы они признаны решить и какие преимущества и недостатки несет тот или иной путь решения.


            1. alexs0ff
              19.09.2017 14:17

              >>историю этого «зверинца» решений:
              Т.е. вы утверждаете, что десктоп отличается от вэба не только в инструментах и средах работы?
              Я вижу пару очень существенных преимуществ вэба — кросплатформенность и легкость деплоя. Обладало хоть что-то на десктопе подобным, все уже были бы на этой технологии.


              1. rockon404
                19.09.2017 14:48

                >>Т.е. вы утверждаете, что десктоп отличается от вэба не только в инструментах и средах работы?
                Простите, но что это за логический кульбит? Я ничего подобного не писал. Ткните пальцем, пожалуйста, где я это утверждаю, не переиначивая смысл изложенного.


                1. alexs0ff
                  19.09.2017 15:12

                  Ткните пальцем, пожалуйста, где я это утверждаю

                  Вот здесь
                  изучить историю этого «зверинца» решений: предпосылки к появлению, мотивацию, недостатки

                  Отсыл к истории обособленности вэба, таким образом я понимаю, что Вы утверждаете, что у него задачи совершенно разные от того же десктопа.


          1. JSmitty
            19.09.2017 22:16

            Соглашусь про мейнтейнеров — когда в проект закидываются тоннами ресурсы — это минимум не дает ему утонуть. Безотносительно его объективного качества.

            Сколько ресурсов потратила MS на свой дотнет — вообще невероятная величина. К ангуляр+ts есть масса вопросов, как технического, так и идеологического характера. Vue.js очень удачно зашел еще и именно на том, что он переосмыслил Angular.js.

            QT — давайте будем честны, очень нишевый продукт, с претензией на всё, и по факту низкой популярностью вне линукс.

            Java — с момента покупки ораклом движения вокруг стало сильно меньше. И про «все из коробки» — ну ок, в дотнете есть какой-то LINQ (ничего в этом не понимаю), а в Java? JPA? Hibernate? JDBC? Где тут «искоробочность»?

            Лучшее, что в Java-мире (imho) происходит — происходит в языках на базе JVM, а не в самом языке Java.

            И про «живучесть» — где тот великий и ужасный DEC? Компьютеры от Xerox? Или хотя бы IBM PC? Много ли людей вспомнит огромную Nortel Networks?

            Гугл тот же вполне себе носитель славной традиции убивать «лишние» проекты (помните может, какой тут хайп на Google Wave нагоняли?). Упомянутый Oracle слил OpenOffice в Apache, где он потихоньку загибается, IBM выкинул на мороз (в опенсоурс) ворох всяких штук (Lotus Symphony — из того, чем я успел попользоваться). Так что размер корпорации: а) не гарантия её живучести; б) тем более не гарантия, что проект не будет выкинут.

            И еще про будущее ангуляра мелкий фактик — интерфейс ютуба переписан на Polymer.


            1. splav_asv
              19.09.2017 22:47

              QT — давайте будем честны, очень нишевый продукт, с претензией на всё, и по факту низкой популярностью вне линукс.

              С нишевостью Qt вопрос. Очень большая доля кросплатформенного софта с GUI это Qt. И даже часть Windows-only. Даже в мобильный мир потихоньку просачивается. Скорее надо читать: с низкой популярностью вне кросплатформенных приложений.

              Или хотя бы IBM PC

              Ну собственно подавляющее большинство машин в настоящее время и есть эволюция IBM PC. Или я не понимаю, что вы хотели сказать.


  1. VladVR
    19.09.2017 12:30
    +8

    Тож немного копеек подкину в холивар. То, что ангуляр основан на бета-фиче тайпскрипта(декораторы) уже обсасывалось не раз. То, что rxjs для веб-запросов — лютый оверенжиниринг — тоже. Все равно что везде для своих переменных использовать массивы.
    Вместо let name = 'Вася', писать let name = ['Вася'] и т.п.
    И реально использующихся потоков в рабочих проектах я еще не встречал. Везде получали один единственный асинхронный ответ. У кого то может и есть реальный кейс, где это полезно, хз, не об этом я сейчас. А о том, что в связи с этим выплыло. Change Detection ангуляра основан на манки-патчах. библиотека zone.js. Когда первый раз про нее читал, вот прям как чувствовал, что даже если эта система будет абсолютно оттестирована и 100% безбажна, все равно где то найдется ситуация, где эта абстракция либо что то не покрывает, либо будет какая то концептуальная дыра. И я на такое наткнулся. Выбросив вышеозначенный rxjs, я стал писать на async/await. Асинхронный код намного приятнее и читабельнее. Но у него есть недостаток — сложно дебажить, потому что компилируется это либо в генераторы для es6, либо в state-machine для es5, и sourcemaps генерируются не лучшим образом, иногда брейкпоинты не ставятся вообще, иногда не на ту строку, на которую хочешь и т.д.
    И недавно я узнал, что оказывается V8 поддерживает async/await нативно. И хром и NodeJs. И я переключил typescript в es2017 для пробы. Дебажить стало супер-удобно, почти так же, как и синхронный код. Но обнаружилось то, о чем уже наверное можно догадаться. await срабатывает вне той зоны, в которой было начало функции. И zone.js в принципе никогда не сможет реализовать поддержку этого. Если конечно поддержку зон не внедрят прямо в js. И я искренне надеюсь что этого не будет.
    То что на антипаттерне основан какой то ui фреймворк, который умрет при следующем изменении моды, или просто с выходом новой версии, это как то плевать, но внедрять антипаттерны в язык это уже лютое зло.


    1. alexs0ff
      19.09.2017 12:50

      >>И реально использующихся потоков в рабочих проектах я еще не встречал
      Реактивное программирование я еще использовал в 2009-2010 годах, то что оно еще живо — многое говорит. Другое дело, что перестроить мозги трудно (как это происходило между процедурным программированием->ООП->функциональным).


  1. VladVR
    19.09.2017 12:40
    -1

    И еще один комент

    Если вам нравится действительно чистый код: Vue

    React+Redux это заведомо чистый код. В функциональном понимании — Pure.
    Код без состояния и сайд-эффектов. Состояние сдвигается в стор, сайд-эффекты соответственно в асинхронные сервисы.
    Что подразумевается под «действительно чистый», не совсем понятно, может ли он быть более чистым, чем то, что чисто по определению?


    1. myrslok
      19.09.2017 12:58

      React+Redux это заведомо чистый код. В функциональном понимании — Pure.

      Ни язык, ни фреймворк не дают таких гарантий.


      А вообще там не pure, а clean.


      1. TheShock
        19.09.2017 16:32
        -1

        А вообще там не pure, а clean.

        Как раз Pure, а не Clean. Хотя редакс — ни Pure, ни Clean.

        edit. Ох, простите, в статье действительно имеется ввиду Clean.


  1. kolesoffac
    19.09.2017 12:51

    Есть мнение(не мое) в поддержку джейкыери для основы проекта — «Все библиотеки и фрайемворки уйдут в не бытиё, а jq останется». Насколько оно справедливо, покажет время, но пока почему-то у меня вызывает улыбку.


  1. Sergiy
    19.09.2017 14:05

    Да они все одинаковые в целом, выбирайте что больше нравится.


  1. Mysterious
    19.09.2017 14:48

    А почему среди всех вопросов в списке нет таких важных как:

    • какая работа с данными нужна нашему проекту
    • как быстро собирается разростатся проект
    • как много динамичных элементов в среднем вам надо на одной странице
    • для чего был задуман изначально тот или иной фреймворк


    Почему все сразу начинают с хайп проектов!?


    1. Synoptic Автор
      19.09.2017 15:17

      Все эти вопросы тут в том или ином виде рассмотрены — про работу с данными есть секция про состояния и биндинги, про разрастание тоже прилично размазано по статье, да и в конце есть:

      Если ваше приложение имеет тенденцию разрастаться: Angular(или React)

      Про количество элементов — имеется раздел про производительность, про изначальную задумку по-моему даже лишнего написано, по несколько абзацев истории фреймворков.

      Что есть не хайп-проекты? Топ фреймворков приведен по ссылке в самом первом абзаце статьи. То, что тут нет популярных, но более узкоспециализированных вещей, типа ExtJS, d3.js, ну так речь тут и не о них.

      Ну а про сравнение фреймворков, поддерживаемых полутора гиками писать, очевидно никому не интересно.


    1. G-M-A-X
      19.09.2017 16:19
      -2

      Потому что это хайповые фрейморки. :)
      Кому не нужен хайп, тот использует jQuery.


      1. kolesoffac
        20.09.2017 09:43

        jQuery — панацея?


        1. G-M-A-X
          21.09.2017 09:02

          А у вас болезнь какая-то? :)
          От добра добра не ищут. :)
          П.С.
          Не судите строго. :)


  1. zenkz
    19.09.2017 22:14
    +1

    Не хочу ни с кем спорить, но попробовав все 3 вещи (правда не в реальных проектах), выбрал и сейчас изучаю Vue.js

    Для меня важна работа из коробки, т.е. минимальное количество софта которое нужно установить и сконфигурировать чтобы начать проект. Также желательно как можно меньше зависимостей от кастомных решений.
    Поэтому Angular мне не подходит из-за наличия TypeScript. (Да, писать на нём приятнее, но необходимость трансляции кода убивает все преимущества). Вернусь к этому вопросу, когда все современные браузеры будут поддерживать его из коробки.
    Другой важный фактор, это удобные средства разработки (с подсветкой синтаксиса, подсказками и прочими плюшками). По этой причине не выбрал Реакт. Т.к. с моей точки зрения идея запихнуть всё в джаваскрипт — это плохая идея.
    В этом плане компоненты Vue — просто идеальное решение. Все 3 части (HTML, JS, CSS) в одном файле и благодаря обёртками в HTML-теги с ними удобно работать.

    Также благодаря простоте Vue будет проще для освоения новыми разрабочиками, а значит будет проще найти подходящих кандидатов. Опять-же это сугубо личное мнение, но может оно кому-нибудь поможет в выборе технологии.


    1. Synoptic Автор
      19.09.2017 22:29

      Если есть некоторый запас терпения, то попробуйте Polymer. Я не работал с Vue. Но после всего, что видел — Polymer действительно крутая вещь. Вообще толком практически ничего лишнего, ни билд-тулов, ни зависимостей, ни своих велосипедов. Тоже при желании все в одном файле, но можно и разнести как хочется. У Vue как я понимаю все же есть дополнительные абстракции, все равно что-то куда то в JS компилится, Virtual DOM, прочие умные вещи. А Polymer — практически jQuery на стероидах, без его минусов(но пока со своими — кроссбраузерность- :().

      А так, ставлю на него и готов терпеливо ждать, пока его перестанет колбасить.


      1. vintage
        20.09.2017 05:24
        +4

        Динамическая загрузка зависимостей — это очень медленно, поэтому для прода полимеры всегда вулканизируют. А это значит: билд-тулы, зависимости и прочие прелести.


        1. Synoptic Автор
          20.09.2017 12:14

          а) на проде я не использовал, страшновато пока
          б) медленно, когда их очень много, а это не всегда так
          в) HTTP/2 можно настроить, по крайней мере это рекомендуют делать вместо вулканизации

          И даже с вулканизацией есть разница — билдить под прод и не билдить во время разработки(билд тулы же во время разработки особо бесят), либо билдить всегда, потому что без билд-тулов не работает ничего.


          1. vintage
            20.09.2017 13:05
            +2

            Мы пробовали под мобилкой запускать. Можно было в реальном времени наблюдать, как он подгружает компоненты и они оживают.


            http2 — не панацея, да и настраивать его — то ещё веселье.


            Отлаживать лучше тот же код, что будет и на проде, так что лучше привыкать к билд-тулам во время разработки. А чем они вас так бесят? Вам же всё равно нужно локальный сервер запускать. Набрали npm start и работайте, а сервер сам всё соберёт по необходимости.


            1. Synoptic Автор
              20.09.2017 13:12

              Ну лично я с продакшен кодом напрямую не работаю, кроме как когда надо чинить prod-specific проблемы, как то не фанат, и с тестами все неплохо.

              Бесят собсно компиляцией, чем дальше в лес, тем дольше, для ангуляра до 20 секунд на крупных проектах ожидание бывает, для реакта тоже долго. Как я понял и для Vue тоже самое будет. Также бесят такой штукой как «еще одна вещь, которую надо знать». Ну ок, я уже со всеми детальками этого механизма разобрался, но это отняло много времени и осадочек остался.

              Про локальный сервер туда же — разница между ng serve и polymer serve в том, что в первом случае на каждый чих что-то происходит, а во втором — ничего не происходит. Ощущение как от написания jquery-плагинов.

              С HTTP2 пока ковыряюсь и надеюсь в какой-то момент родить статью о его настройке под этот конкретный кейс. С учетом получаемых плюшек, не так и много там настраивать.


              1. vintage
                20.09.2017 13:41
                -1

                Ангуляр не просто транслирует код, но и проверяет его на корректность благодаря typescript. Просто трансляция (как в случае всяких vue/react) проходит налету. Собственно и для TS можно выключить проверку типов и компиляция будет летать. У нас весь $mol на горячую билдится примерно 6 секунд (с проверкой корректности, конечно). Хочу в ближайшее время попробовать одну идею с инкрементальной компиляцией, которая теоретически должна сократить время горячего билда на порядок без потери проверки корректности.


                1. Synoptic Автор
                  20.09.2017 13:45

                  Все это так. Неплохо бы иметь такое опционально и в том же Polymer, но именно что опционально. Ведь даже после отключения всего что можно в Angular, меньше 1-2 секунд компилиться он не будет.

                  В React можно обойтись без билд-тулов, но(не не тестил) есть серьезные сомнения, что производительность от трансляции на лету не загнется даже на среднего размера приложении(скажем, средненький шоп). В Polymer в этом плане проще так как там транслировать толком нечего.


                  1. vintage
                    20.09.2017 13:49

                    Ну, 1-2 секунды — вполне приемлемая скорость. Особенно в свете того, что крупное приложение на Ангуляре только запускаться будет 5 секунд :-D


                    1. alexs0ff
                      20.09.2017 14:01

                      В коде можно такого написать, что и чистый JS будет запускаться пару минут


                      1. vintage
                        20.09.2017 14:06

                        В одних фреймворках это может получиться непреднамеренно, а в других — надо специально постараться.


                        1. alexs0ff
                          20.09.2017 14:07

                          AOT решит проблему в случае с ангуларом.


                          1. vintage
                            20.09.2017 14:26

                            Не решит. Ну пример из жизни: запилили ребята табличку на Ангуляре. Набросали тестовых данных, потестили, всё ок. Выкатили. В течении месяца объём реальных данных вырос — опа страница открывается 10 секунд. И это в свете того, что интересуют как правило несколько верхних записей.


                            1. alexs0ff
                              20.09.2017 15:41

                              >>cтраница открывается 10 секунд
                              Эм, я что-то не понимаю…
                              Причем тут данные и открытие страницы.
                              В моих SPA обычно происходит, так.
                              Запускается приложение-> Отправляем запрос на данные->Показываем пользователю, что выполняется AJX запрос-> Данные приходят->Мы их отображаем.
                              При таком раскладе, от количества данных ну никак не может зависеть время старта приложения.


                              1. vintage
                                20.09.2017 16:24

                                А пользователю какой прок от того, что он вместо браузерного крутящегося колёсика видит ваше? Он пришёл к вам за данными.


                                1. alexs0ff
                                  20.09.2017 16:32

                                  >>А пользователю
                                  Так получается дело не в старте приложения, а в в большом времени получения/рендерига данных.
                                  В случае если Ajax запросы проходят долго, то дело вовсе не с ангуларом.
                                  А вот если отрисовывается долго, то нужно смотреть, сколько там данных и каковы шаблоны отображения. Но у меня проблем с rendering не было.
                                  Вангую — не был включен Prod режим у angular.


                                  1. vintage
                                    20.09.2017 16:56

                                    Я же написал: данных было много — таблица долго рендерилась. Это первый ангуляр, какие ещё режимы? :-)


                                    1. alexs0ff
                                      20.09.2017 16:59

                                      В ветке был упомянут TypeScript вот я и решил, что это про Angular2+


                  1. raveclassic
                    20.09.2017 13:50

                    Так у реакта же есть удобный HMR, зачем пересобирать постоянно все приложение, когда можно пересобирать один компонент


                    всмысле react-hot-loader, а не обычный HMR


                    1. Synoptic Автор
                      20.09.2017 14:09

                      Это лучше, но сравнению моментальностью в Polymer разница все равно существенная. Опять же, это лишнее место, где что-то может сломаться. Я стараюсь число таких мест сводить к минимуму.


      1. kolesoffac
        21.09.2017 15:00

        А я как раз в polymer разочаровался, в виду выясненных багов с dom-repeat, и фризы при реализации конкретного проекта на нем. Позже весь проект переписал на vue(дабы вся логика была зашита в редакс), и теперь радуюсь — данные проблемы производительности ушли. Но хотя полимер по своему хорош, но vue все таки лучше.


        1. Synoptic Автор
          21.09.2017 15:12

          А можете, хотя бы в двух словах по-подробнее, или может есть линки на ишуи?
          Redux при желании можно прикрутить без проблем и к Polymer, хотя вы явно в курсе, у вас статья про это есть.


          1. kolesoffac
            21.09.2017 15:16
            +1

            >>Redux при желании можно прикрутить без проблем и к Polymer, хотя вы явно в курсе, у вас статья про это есть.
            А думаете почему я так относительно быстро перешел на vue? Потому что бизнес-логика была уже реализована, и оставалось обернуть ее во vue.

            А так подробности здесь.


            1. VolCh
              21.09.2017 21:27

              Вот чем мне нравится подход "берём библиотеки и склеиваем их" (вариант "берём склеенные кем-то библиотеки"), что всегда можно малой кровью заменить одну библиотеку на другую. С огромными фреймворками обычно такое не проходит, и даже если формально он компонентный, то очень часто ко мпоненты сильно связаны, типа компонент формы и компонент валидации.


              1. vintage
                21.09.2017 21:36

                А в чём проблема подменить компонент валидации/формы на адаптер к другой библиотеке?


  1. PaulMaly
    19.09.2017 22:44
    -1

    Ага, выбрал — Ractive и нет проблем с выбором фреймверка))))


    1. lega
      19.09.2017 22:59
      -1

      Но у него же вообще нет преимушеств перед хайповыми фреймворками.


      1. PaulMaly
        20.09.2017 01:07
        -1

        С чего вы взяли? ))) Vue вообще изначально с него слизывали, что сильно заметно на базовых примерах. После того как попробуешь Ractive проблемы возникающие при использовании React и даже Vue (при всем моем уважении) заставляют на него вернуться. Сколько не писал на других фреймверках, каждый раз ловлю себя на мысли, зачем я так мучаюсь.


        1. raveclassic
          20.09.2017 01:22
          +1

          А в чем основное преимущество?


          1. PaulMaly
            20.09.2017 09:46

            Боюсь что дать ответ на столь объемлющий вопрос в рамках комментария мне будет не просто)) Если краткой — он просто работает так, как от него ожидается, без лишней «магии», «танцев с бубнами» и других шаманств, чего часто не хватает другим фреймверкам. При этом он умеет все тоже самое, что и остальные и даже больше. И когда дело доходит не до примеров из документации, а до реальных, не всегда тривиальных проблем, я всегда нахожу встроенное решение в Ractive, без костылей и установки дополнительных модулей.

            На ходу более конкретно сложно придумать (можем обсудить более обстоятельно в личке), но например нам нужно прикрутить один из сотен тысяч крутых jquery-плагинов в нашему не менее крутому реактивному приложению, но вот незадача плагин меняет DOM, а реактивный фреймверк об это и не в курсе и наоборот. Задача ясна — нужно засинкать состояние плагина и реактивных данных. Реализации можно осуществить, с тем или иным успехом, на любом фреймверке, но если в Vue и React, нам понадобиться обернуть Jquery плагин в целый компонент, со всеми вытекающими (сразу представляем форму с 20-ю кастомными инпут полями, каждый из которых это компонент, внутри которого обернут jqeury плагин), то в Ractive это всего то написать одну функцию. Одну функцию, Карл!

            Называется это Декоратором и внутри этой функции можно спокойненько сотворить любые нужные действия. При это Ractive заботливо пробросит внутрь не только нужную ноду, но еще и необходимые реактивные переменные, любые параметры, которые потребуются и текущий инстанс самого Ractive (точнее декоратор будет выполнен в его контексте). Выглядеть это будет примерно так (юзаем webpack):

            // Пример декоратора
            module.exports = (node, date) => {
              const $$ = this, 
                    $el = $(node);
            
              $el.datepicker({
                onSelect: (val) => {
                  $$.fire('datepicker:selected', val); // проксируем любые ивенты, которые поддерживает сам плагин
                }
              });
            
              return {
            	teardown: () => {
            		$el.datepicker('destroy'); // не забываем подчистить плагин когда он будет не нужен
            	},
                update: (date) => {
            		$el.datepicker('setDate', date);
                }
              };
            
            }
            
            // Регистрация в инстансе
            const $$ = new Ractive({
                data: {
                	date: Date.now()
              	},
                decorators: {
            		datepicker: require('./decorators/datepicker')
              	}
            });
            

            // В шаблоне, так как включен twoway-binding значение date будет изменяться автоматом
            <input as-datepicker="date" value="{{ date }}">
              

            // Так тоже будет работать и плагин корректно отобразит установленную вручную дату
            $$.set('date', Date.now());
            


            Можно выключить двойное связывание для всего инстанса или даже для конкретного инпута и использовать проксируемый ивент:
            // Выключаем twoway-binding
            <input as-datepicker="date"  value="{{ date }}" twoway="false">
              

            // слушаем ивент и изменяем значение реактивной переменной в функции makeSomeNoice
            $$.on('datepicker:selected', makeSomeNoice);
            


            Пример не самый сложный, но думаю раскрывает возможности.

            Еще пример — хотим писать результат асинхронной операции прямо в реактивную переменную, со всеми вытекающими плюшками (напрямую так делать не хорошо, но мы все равно хотим), чтобы можно было сделать примерно так:
            $$.set('products', $.getJSON('/api/products'));
            

            Нет проблем, берем или пишем сами (20 строк кода) Promise Adaptor и делаем.

            // Регистрация в инстансе
            const $$ = new Ractive({
              data: {
                products: []
              },
              adapt: [
                require('./adaptors/promise')
              ]
            });
            

            И ведь это никакой не мега-магический-компонент, или дополнительный модуль аля react-{whatever}, это обычный js объект с 2-мя функциями. Все.

            Или вот, еще двойное связывание. В React его нет, в Vue ужасный синтаксис:
            // vue style
            <select v-model="selected">
              <option v-for="option in options" v-bind:value="option.value">
                {{ option.text }}
              </option>
            </select>
              
            // ractive style 
            <select value="{{ selected }}">
                {{#options}}
                <option value="{{ .value }}">{{ .text }}</option>
                {{/options}}
            </select>
            

            Да и вообще увлеченность Vue ангуляроскими дерективами это капец. Иной раз такие длинющие выражения получаются в тегах. Про React вообще молчу, там и шаблонов то нет, поэтому верстальщики (да да, такие люди еще есть) страдают неимоверно, когда работают с JSX. А когда страдает верстальщик, он заставляет страдать программиста. Проверено на собственном опыте.

            А вы что используете в работе? Не хотите устроить пари на эту тему?


            1. raveclassic
              20.09.2017 10:08

              Мм, ну вы же все-равно пишете декоратор, а потом для него аттрибут. Какая тогда разница, если можно написать компонент с таким же пробросом всего во все стороны, а потом вместо аттрибута просто отрендерить его?


              Я просто не сторонник подмешивания логики через аттрибуты, слишком это по-ангуляровски. По мне так если есть какая-то конечная логика, она должна сидеть в конечном компоненте. А смешивание должно идти через композиции в компоненте, а не добавлением вороха аттрибутных директив в разметке.


              Но по поводу плагинов jquery, наверное, можно согласиться. Хотя я уже давно ими н пользуюсь и не припомню, чтобы мне какой-то из них понадобился.


              Про двойное связывание уже немало голосовых связок порвано. Я тут противник.


              По поводу рыданий верстальщиков от JSX — вот и нет :) Проверено на собственном опыте.


              А вы что используете в работе?

              В основном Реакт, как вы уже наверное догадались. Но есть оба (1 и 4) ангуляра, но они беспросветное днище.


              1. PaulMaly
                20.09.2017 10:35

                Какая тогда разница, если можно написать компонент с таким же пробросом всего во все стороны, а потом вместо аттрибута просто отрендерить его?

                Потому что компонент это как правило «дороже» чем вызов функции. Не зря же я упомянул про форму с 20ю инпутами. Компонент это целый механизм и он не нужен для такой мелкой задачи как синхронизировать две либы.

                Я просто не сторонник подмешивания логики через аттрибуты, слишком это по-ангуляровски. По мне так если есть какая-то конечная логика, она должна сидеть в конечном компоненте.

                Ну как сказать по-ангуляровски. Вы же наверное не раз в жизни делали вот так:
                <input class="datepicker">
                

                А какой-нить подключенный плагин или иной код автоматом вешался на этот класс. В целом это не отличается от использования декоратора, только декоратор используется более прозрачно.
                А смешивание должно идти через композиции в компоненте, а не добавлением вороха аттрибутных директив в разметке.

                С теоритической точки зрения верно. Однако на практике могут быть на первый взгляд не значительные особенности использования в каждом конкретном случае, которые либо придется разруливать внутри компонента (лишние условия и тп), либо писать его вариации для каждого случая. Простой пример с twoway:
                <date-picker></date-picker> // нужно toway
                <date-picker></date-picker> // не нужно toway
                

                Как будем решать? Вероятно вводим prop, но тогда в чем разница:
                <date-picker twoway="false"></date-picker>
                <input twoway="false">
                

                Про двойное связывание уже немало голосовых связок порвано. Я тут противник.

                Нет проблем, я также признаю что это не безопасная вещь и ее нужно использовать осторожно. Поэтому Ractive позволяет ее отключить как на уровне компонента, так и для каждого конкретного поля:
                <input twoway="false">
                

                const $$ = new Ractive({
                  twoway: false,
                  lazy: true // еще одна прикольная опция, которая работает как для всего инстанса, так и для конкретного инпута
                });
                

                По поводу рыданий верстальщиков от JSX — вот и нет :) Проверено на собственном опыте.

                Посмотрел бы я на верстальщиков, которым удобно работать с мелкими кусочками html-подобного «текста» внутри js, вместо нормального html файла без лишнего «шума» и с хорошей подсветкой )) Реально, таких надо по ТВ показывать, у Малахова, чтобы все о них знали. )))
                В основном Реакт, как вы уже наверное догадались. Но есть оба (1 и 4) ангуляра, но они беспросветное днище.

                Да, на 1-м писал, утомил. 4(2) даже пробовать не стал. На React тоже писал, но JSX и микро-компонентный подход, а также сложности с конфигурированием (ну чтобы работало нормально) не прижились у меня. Слишком много испытывал сложностей со слишком простыми вещами. Не могу писать на фреймверке, где иной раз приходится один компонент оборачивать в другой, чтобы решать примитивную задачу. Но это мое имхо, на вкус и цвет…


                1. raveclassic
                  20.09.2017 12:18
                  +1

                  Потому что компонент это как правило «дороже» чем вызов функции.

                  Компонент тоже может быть функцией — SFC. Ну и что, что сначала через vdom все прогоняется, ractive в кишках с этими декораторами тоже без дела не сидит. Так что совсем без разницы. Ну и на сколько там это все дороже? Спички


                  Вы же наверное не раз в жизни делали вот так

                  Ну было дело, где-то в универах. Сейчас я за такое больно по рукам бью. Класс отвечает за внешний вид.


                  Однако на практике могут быть на первый взгляд не значительные особенности использования в каждом конкретном случае, которые либо придется разруливать внутри компонента (лишние условия и тп), либо писать его вариации для каждого случая

                  Это не совсем так, я же не про атрибуты, а про логику сбоку, которая цепляется к компоненту, видя на нем этот атрибут. А если у вас два, три, десять таких атрибутов и они между собой конфликтуют? Привет angularjs и priority. В случае композиции HOC вы явно указываете порядок применения и всегда порождаете новый компонент.


                  Реально, таких надо по ТВ показывать, у Малахова, чтобы все о них знали. )))

                  Как там говорилось, "Видишь суслика?" :) Ну реально, целая команда сидит довольная. А раньше на hbs и первом ангуляре колбасили, сейчас нарадоваться не могут.


                  один компонент оборачивать в другой, чтобы решать примитивную задачу

                  Так это ж прелесть композиции. Вы собираете решение из примитивных переиспользуемых кусочков.


                  1. PaulMaly
                    20.09.2017 15:36

                    Компонент тоже может быть функцией — SFC. Ну и что, что сначала через vdom все прогоняется, ractive в кишках с этими декораторами тоже без дела не сидит. Так что совсем без разницы. Ну и на сколько там это все дороже? Спички

                    Не думаю что stateless компонент это хороший пример в этом случае, а если писать полноценный компонент он будет «дороже», а уж на спички или нет, это надо смотреть. Опять же форма из 20-ти инпутов может превратиться в 100 не импутов, а чего-то сложнее. Тогда уже и на коробок наберется. Однако основная идея в другом — суть задачи лишь в том, что 2 либы друг с другом не дружат по умолчанию, ибо разные подходы и вендоры. Дружить их с помощью компонентов по меньшей мере странно. Компонент, в моем понимании, являются строительным материалом для приложения и ни как уж не должен служить таким мелким, чисто утилитарным целям. Однако дело ваше. Как я уже говорил, React стремиться к микро-компонентам, лично мне это претит.

                    Ну было дело, где-то в универах.

                    Видимо не давно вы универ закончили.))) Когда я заканчивал jquery был как раз на коне, а вместе с ним куча плагинов которые так и работали. Да и Bootstrap еще не умер и там такое сплошь и рядом.
                    Сейчас я за такое больно по рукам бью. Класс отвечает за внешний вид.

                    Вот именно, поэтому так делать нельзя. А декораторы как раз созданы для этого, так что натыкаясь на такую дерективу в шаблоне сразу понятно, что происходит.
                    Это не совсем так, я же не про атрибуты, а про логику сбоку, которая цепляется к компоненту, видя на нем этот атрибут. А если у вас два, три, десять таких атрибутов и они между собой конфликтуют?

                    Не согласен про логику сбоку — это всего лишь связка между двуми либами. В «прекрасном мире будущего» она вообще будет не нужна и все новые либы будут из коробки синхронизироваться между собой. Поэтому это не «логика сбоку» это устранение несовершенства. Да и логики там особой нет, данные туда, данные сюда, адаптация двух интерфейсов, не более. Про то, почему это не должно быть компонентом, написал выше.
                    Так это ж прелесть композиции. Вы собираете решение из примитивных переиспользуемых кусочков.

                    Один мой друг показывал проект на React где он обернул вообще все в компоненты. У него даже иконка, которая ничего не умела делать была компонентом. Да композиция вероятно хорошая получилась, но для меня это ничто иное как components-hell (оцените иронию ;) ) Лично я не пытаюсь все запихнуть в компоненты, на мой извишняя композиция излишне усложняет код. Также я не пишу «сверх универсальные» компоненты, которые можно включить в любые другие компоненты. Как правило такое сделать не получается, либо получается, но не слишком прямо. Может скажу маргинальную вещь, но для меня компонент — это аналог класса, т.е. штука которую можно инстанциировать с разными входными параметрами и которая требует некоторой степени инкапсуляции (например решает явно обособленную задачу). Все = компонент, это не мой подход.


                    1. raveclassic
                      20.09.2017 16:01

                      Опять же форма из 20-ти инпутов может превратиться в 100 не импутов, а чего-то сложнее.

                      Так может стоит ее побить на подкомпоненты (филдсеты например) вместо портянки?


                      Компонент, в моем понимании, являются строительным материалом для приложения и ни как уж не должен служить таким мелким, чисто утилитарным целям.

                      Компонент — это логическая единица, строительный блок в рамках приложения. А то, что у него в кишках jquery плагин — это детали реализации. Ну тут действительно, чего спорить.


                      Видимо не давно вы универ закончили.))) Когда я заканчивал jquery был как раз на коне, а вместе с ним куча плагинов которые так и работали. Да и Bootstrap еще не умер и там такое сплошь и рядом.

                      jQuery тут вообще не причем. Такой фигней и до нее занимались, навешивание логики через селекторы по классам, атрибутам… Помним, скорбим. Ну и то, что написана куча говна плагинов и бутстрапов — еще не говорит, о том, что это правильно.


                      А декораторы как раз созданы для этого, так что натыкаясь на такую дерективу в шаблоне сразу понятно, что происходит.

                      Вообще не понятно, вам нужно помнить, что ваша "директива" вот так работает на инпуте, вот этак на кнопке, а на таблице вообще не работает. Вместо того, чтобы зашить эту логику в компоненте и забыть.


                      Не согласен про логику сбоку — это всего лишь связка между двуми либами.

                      Это слишком низкоуровнево. То, что часть логики лежит в либе, вообще знать не нужно.


                      Не согласен про логику сбоку — это всего лишь связка между двуми либами. В «прекрасном мире будущего» она вообще будет не нужна и все новые либы будут из коробки синхронизироваться между собой. Поэтому это не «логика сбоку» это устранение несовершенства. Да и логики там особой нет, данные туда, данные сюда, адаптация двух интерфейсов, не более. Про то, почему это не должно быть компонентом, написал выше.

                      Крайне странный подход. Даже спорить не буду


                      У него даже иконка, которая ничего не умела делать была компонентом.

                      Разве иконка — это не компонент?


                      Лично я не пытаюсь все запихнуть в компоненты, на мой извишняя композиция излишне усложняет код.

                      Как раз упрощает. Интерфейс строится из компонентов, слой за слоем, от простых к сложным. Вместо лапши из атрибутов и копипасты маркапа для спорных библиотек.


                      Также я не пишу «сверх универсальные» компоненты, которые можно включить в любые другие компоненты. Как правило такое сделать не получается, либо получается, но не слишком прямо.

                      Вот и зря, теряете в переиспользуемости, либо проекты такие не попадались. Все там получается, вот только прямо — действительно только с реактом.


                      (например решает явно обособленную задачу)

                      Разве все не решает явно обособленную задачу?




                      В общем, что тут. Преимущества Ractive особо-то не описаны, только лишь низкоуровневые утилики для связки с жквери. Но, все-равно, спасибо за развернутые ответы.


                      1. PaulMaly
                        20.09.2017 16:57

                        Так может стоит ее побить на подкомпоненты (филдсеты например) вместо портянки?

                        А если не получится? Зачем вообще связку 2-х либ делать компонентом, я понять не могу?
                        Компонент — это логическая единица, строительный блок в рамках приложения.

                        Именно так, но если это строительная единица, причем тут jquery плагин, который просто делает ввод значение в инпут более удобным? Если бы в браузере был такой инпут встроен, вы бы его тоже в компонент обернули? Какая-такая бизнес-логика в нем присутствует, что требует писать компонент, который, как вы написали, есть строительная единица? Да блин, он всего лишь позволяет пользователю не вписывать «20/09/2017» в поле текстом и все!
                        Ну и то, что написана куча говна плагинов и бутстрапов — еще не говорит, о том, что это правильно.

                        Это не правильно, да. Но в целом конуепция деректив не плоха, если конечно не начинать делать абсолютно все с их помощью как это делают в Angular и, к сожалению, в Vue.
                        Вообще не понятно, вам нужно помнить, что ваша «директива» вот так работает на инпуте, вот этак на кнопке, а на таблице вообще не работает.

                        Вообще не надо помнить, читайте код:
                        <input as-datepicker>
                        

                        Убираем <>, «input as datepicker», тут даже верстальщик догадается )))
                        Вместо того, чтобы зашить эту логику в компоненте и забыть.

                        А помнить что у вас в компоненте, как он принимает параметры, куда записывает значение вам не нужно что ли? Ну да. Смотрим взглядом стороннего наблюдателя:
                        <my-datepicker></my-datepicker> <!-- что это вообще? куда значение пишется? как его получить? лезем в компонент смотреть -->
                        <input as-datepicker> <!-- это инпут с виджетом выбора даты. значение можно получить через node.value -->
                        

                        Это слишком низкоуровнево. То, что часть логики лежит в либе, вообще знать не нужно.

                        Так и я о том. Декораторы позволяют написать один раз связку с другой либой и забыть. А само приложение мы пишем на компонентах и решаем свои бизнес-задачи с их помощью.
                        Разве иконка — это не компонент?

                        Тяга к микро-компонентному подходу на лицо. React к этому склоняет, это факт.
                        Как раз упрощает. Интерфейс строится из компонентов, слой за слоем, от простых к сложным. Вместо лапши из атрибутов и копипасты маркапа для спорных библиотек.

                        Крайне странный подход. Даже спорить не буду, но подобного кода повидал не мало и он всегда сложее для понимания и правок.

                        Вот и зря, теряете в переиспользуемости, либо проекты такие не попадались. Все там получается, вот только прямо — действительно только с реактом.

                        Ну ну, а вы заметили что разговор перешел в разряд «веры», так может все же пари? Там глядишь и вы свои «сверх универсальные» компоненты покажете, ну и я смогу описать преимущества точнее. Было бы интересно))


                        1. raveclassic
                          20.09.2017 17:13

                          А если не получится? Зачем вообще связку 2-х либ делать компонентом, я понять не могу?

                          А что может не получиться? И где вообще связь между огромной формой и либами?


                          Именно так, но если это строительная единица, причем тут jquery плагин, который просто делает ввод значение в инпут более удобным? Если бы в браузере был такой инпут встроен, вы бы его тоже в компонент обернули?

                          Я же навешивую доп.логику на стандартный браузерный инпут? Значит, компонент.


                          Какая-такая бизнес-логика в нем присутствует, что требует писать компонент, который, как вы написали, есть строительная единица?

                          Да вот такая:


                          Да блин, он всего лишь позволяет пользователю не вписывать «20/09/2017» в поле текстом и все!

                          Я не любитель полумер. Это что значит, если логики кот наплакал, так и фиг с ней? Компонент можно не выделять?


                          <input as-datepicker/>

                          <input as-datepicker/>, <input type="email" as-datepicker/>, <input as-datepicker as-colorpicker/>, <textarea as-datepicker/> да полно примеров


                          Декораторы позволяют написать один раз связку с другой либой и забыть.

                          Чем это отличается от компонентов?


                          Тяга к микро-компонентному подходу на лицо. React к этому склоняет, это факт.

                          Эээ, как будто в этом что-то есть плохое. Как переиспользуемые куски кода уезжают в функции, так и куски разметки уезжают в компоненты. Еще и с логикой заинкапсулированной, если она есть. К этому склоняет не только Реакт, к этому склоняет вообще весь фронтенд на данный момент. Видимо только Ractive не склоняет =(


                          Ну ну, а вы заметили что разговор перешел в разряд «веры»

                          Вера, не вера, не в этом дело. Я вас спросил про преимущества изначально. Преимуществ, не увидел, к сожалению.


                          так может все же пари? Там глядишь и вы свои «сверх универсальные» компоненты покажете, ну и я смогу описать преимущества точнее. Было бы интересно))

                          Так давайте, я ж не против.


                          1. PaulMaly
                            20.09.2017 18:06

                            А что может не получиться? И где вообще связь между огромной формой и либами?

                            Ну например по какой логике вы обернете 101 элемент в сеты? по 50 и 51 ?)))) Связь в том, что 101 компонент, со всей встроенной мишурой, life-cycle и тп априори «дороже» чем 101 вызов функции.
                            Я же навешивую доп.логику на стандартный браузерный инпут? Значит, компонент.

                            Я же вам пишу, что данный инпут будет стандартным, без jquery плагина. Прям бац и datepicker встроенный в браузер. Будем в компонент оборачивать?
                            Я не любитель полумер. Это что значит, если логики кот наплакал, так и фиг с ней? Компонент можно не выделять?

                            А в чем логика то? Инпут как принимал текстовое значение так и принимает. Вся доп. логика внутри уже обособленного компонента — jquery плагин называется. Какая такая логика будет в вашем компаненте-обертке? Только логика связывания плагина и реактивных данных, но это же не логика приложения, это просто низкоуровневая задача продиктованная тем, что плагин не умеет реактивность. Зачем тут компонент, который есть строительный материал приложения, а значит должен заниматься бизнес-логикой, а не мелкими утилитарными задачами.

                            <input as-datepicker/>, <input type=«email» as-datepicker/>, <input as-datepicker as-colorpicker/>, <textarea as-datepicker/> да полно примеров

                            Это что за бред? Зачем поле email делать пикером даты? Притянуто за уши не понятно к чему вообще.
                            Чем это отличается от компонентов?

                            А разве компонент — это строительный блок вашего приложения? Разве вы его создаете не чтобы решать задачи приложения? Разве связка с плагином jquery является задачей вашего приложения?
                            Эээ, как будто в этом что-то есть плохое. Как переиспользуемые куски кода уезжают в функции, так и куски разметки уезжают в компоненты. Еще и с логикой заинкапсулированной, если она есть. К этому склоняет не только Реакт, к этому склоняет вообще весь фронтенд на данный момент. Видимо только Ractive не склоняет =(

                            Не правда))) Только React (и его клоны) склоняют к микро-компонентному подходу. Ни Angular, ни Vue, ни Ractive.
                            Вера, не вера, не в этом дело. Я вас спросил про преимущества изначально. Преимуществ, не увидел, к сожалению.

                            Так давайте, я ж не против.

                            Раз не увидели, давайте тогда посмотрим на ваш код, в реализации тех же задач:
                            1. Интегрировать jquery плагин (любую другую dom либу)
                            2. Зареактивить промис (любой другой класс)
                            3. Отобразить select и обновить значение при изменение значения select

                            go?


                            1. raveclassic
                              20.09.2017 18:37

                              Ну например по какой логике вы обернете 101 элемент в сеты? по 50 и 51 ?))))

                              Семантически.


                              Связь в том, что 101 компонент, со всей встроенной мишурой, life-cycle и тп априори «дороже» чем 101 вызов функции.

                              А вы замеряли? Инициализацию шаблона ractive, прогон по этим аттрибутам? Я не вижу смысла гоняться с микробенчмарками, так что спор тут бесполезен.


                              Я же вам пишу, что данный инпут будет стандартным, без jquery плагина. Прям бац и datepicker встроенный в браузер. Будем в компонент оборачивать?

                              99.9...% навороченных браузерных инпутов (те, которые бац и дейтпикер, бац и колорпикер и т.п.) непригодны к использованию, так что, да, оборачивать. Были бы они нормальные, не оборачивал бы.


                              jquery плагин называется

                              Это не компонент :) это манкипатчинг браузерного инпута в рантайме. Нет уж :)


                              а не мелкими утилитарными задачами.

                              А зачем делить на компоненты и плагины, когда можно просто использовать компоненты и забыть уже jquery.


                              Это что за бред? Зачем поле email делать пикером даты? Притянуто за уши не понятно к чему вообще.

                              Ой не бред, и, нет, не притянуто. Это узкий случай и просто пример. В большее общем случае, коих тысячи, вам нужно помнить что вот это с этим сочетается, а это нет. Когда можно просто использовать самодостаточный компонент. Как вы с вашими глобальным "декораторами", которые являются обычными директивами из ng1, сделаете разное поведение на разных базовых контролах? На кнопке одно, на инпуте другое? Флагом внутри декоратора? Ну привет, OCP.


                              А разве компонент — это строительный блок вашего приложения? Разве вы его создаете не чтобы решать задачи приложения? Разве связка с плагином jquery является задачей вашего приложения?

                              Нет, связка с jquery — не является. Задача приложения лежит на другом уровне абстракции, нежели связка с плагинчиками. Даже если они есть (было что-то, wysiwyg вроде), это все спрятано глубоко-глубоко в компоненте, у которого свой интерфейс, никак не завязанный на подключенную внутри либу.


                              Не правда))) Только React (и его клоны) склоняют к микро-компонентному подходу. Ни Angular, ни Vue

                              Аххахха, что?? :D


                              Интегрировать jquery плагин (любую другую dom либу)

                              type Props = {
                                  onChange: (value: string) => any,
                                  value: string
                              };
                              
                              class Wrapper extends Component<Props> {
                                  private el: Element;
                                  private plugin: any;
                              
                                  componentDidMount() {
                                      this.plugin = initPlugin(findDOMNode(this.el));
                                      this.plugin.onChange(this.props.onChange);
                                  }
                              
                                  componentWillUnmount() {
                                      this.plugin.destroy();
                                  }
                              
                                  componentWillReceiveProps(props: Props) {
                                      this.plugin.setValue(props.value);
                                      if (this.props.onChange !== props.onChange) {
                                          this.plugin.resetOnChange(props.onChange);
                                      }
                                  }
                              
                                  render() {
                                      return (
                                          <div ref={(el: any) => this.el = el}></div>
                                      );
                                  }
                              }

                              Зареактивить промис (любой другой класс)

                              Реактивность чего бы то ни было не относится к Реакту. Для этого есть целый зоопарк, начиная с rxjs/most.js и ко и заканчивая всякими mobx'ами.


                              Отобразить select и обновить значение при изменение значения select

                              type State = {
                                  value: string
                              };
                              
                              class SelectWithValue extends Component<{}, State> {
                                  render() {
                                      const { value } = this.state;
                              
                                      return (
                                          <div>
                                              <select value={value} onChange={this.handleChange}>
                                                  <option value="1">1</option>
                                                  <option value="2">2</option>
                                                  <option value="3">3</option>
                                              </select>
                                              Value: {value}
                                          </div>
                                      );
                                  }
                              
                                  private handleChange: ChangeEventHandler<HTMLSelectElement> = e => {
                                      this.setState({
                                          value: e.target.value
                                      });
                                  }
                              }


                              1. PaulMaly
                                20.09.2017 23:39

                                Семантически.

                                А подробнее можно? Вот верстка:
                                <input id="dp1" class="datepicker">
                                <input id="dp2" class="datepicker">
                                <input id="dp3" class="datepicker">
                                <input id="dp4" class="datepicker">
                                .......
                                <input id="dp13" class="datepicker">
                                

                                Были бы они нормальные, не оборачивал бы.

                                Вот и считайте, что декоратор незримо для вас делает из обычного инпута нормальный. И вашим компонентам лишь остается получать оттуда значения.
                                А зачем делить на компоненты и плагины, когда можно просто использовать компоненты и забыть уже jquery.

                                Потому что ни React, ни Vue еще долго не дотянут до того кол-ва всякой всячины, которая была понаписана для JQuery, а когда будут приближаться, им на смену уже прибежит какой-нить то «Шмеракт», которых всех затмит, скажет что теперь надо не на мелкие компоненты делить код, а вообще на символы. Так гибче и композиция лучше. И все дружно бросятся писать «шмеракт-символ-компоненты». Нет смысла отказываться от рабочих решений только потому, что они еще не переписаны на ваш любимый фреймверк.

                                Когда можно просто использовать самодостаточный компонент.

                                А вы как будете помнить, какой компонент надо использовать?
                                Как вы с вашими глобальным «декораторами», которые являются обычными директивами из ng1, сделаете разное поведение на разных базовых контролах? На кнопке одно, на инпуте другое? Флагом внутри декоратора? Ну привет, OCP.

                                Да зачем мне это нужно то? Если тот же jquery плагин не делает этого внутри себя, зачем мне это делать? Цель всего лишь сделать jquery реактивным, не более того.
                                Аххахха, что?? :D

                                Юмора я так и не смог оценить. Ни разу не видел в том же Angular компонента «иконка», а для последователей React это нормально. Такие вещи вообще на стороне css решаться должны, это блин дизайн чистой воды.

                                Интегрировать jquery плагин (любую другую dom либу)

                                Что и требовалось доказать))) Так и не понял, откуда взялить всякие там initPlugin, findDOMNode. Почему jquery плагин вдруг стал обладать методом onChange, destroy, resetOnChange и тп. Сдается мне вы тут упустили еще дополнительную обертку над самим плагином. Ну да ладно, давайте проверим:
                                • При реднаринге вышестоящего компонента, плагин подключается и инициализируется существующим значением, которое может приходить их родительского компонента?
                                • Когда плагин выполняет свою работу, и пользователь выбирает значение, проперти value обновляется?
                                • Когда другой код (например родительский компонент), обновляет проперти value, плагин понимает что значение изменилось?
                                • Плагин дает прописать коллбек, чтобы сообщать,
                                  что значение изменилось. Любой другой компонент может получить уведомление об этом изменении?
                                • Почему jquery плагин инициализируется div'ом,
                                  а не input'ом как в его документации? Внутри функции initPlugin происходит динамическое добавление input в DOM ?
                                • Откуда берутся вспомогательные функции типа initPlugin и findDOMNode? Они глобальные, или импортятся в файл с компонентом?

                                Сдается мне вы не до конца поняли задачу. Можете еще написать как данный компонент будет использоваться?

                                Реактивность чего бы то ни было не относится к Реакту. Для этого есть целый зоопарк, начиная с rxjs/most.js и ко и заканчивая всякими mobx'ами.

                                Причему тут Rx-то? Я про другую реактивность говорю. Еще раз, вам нужно отрендерить значение промиса. Пример на Ractive:
                                const $$ = new Ractive({
                                  data: {
                                    products: []
                                  },
                                  adapt: [
                                    require('./adaptors/promise')
                                  ]
                                });
                                $$.set('products', $.getJSON('/api/products'));
                                

                                Вот шаблон:
                                {{#products}}
                                {{.title}} - {{/.price}}
                                {{/products}}
                                

                                Соответственно шаблон отрендариться автоматически, когда придут данные с сервера. Как видите специально пишу на общеизвестных вещах, типа JQuery.getJSON, без всяких там непойми откуда взявшихся getProductsFromApi, findDOMNode и тп
                                Как такое сделать на React?

                                Отобразить select и обновить значение при изменение значения select

                                Опять не по условию задачи. Есть динамический массив options. Select должен заполняться на его основе. Причем, если массив был изменен, селект также должен пере-рендариться. При этом, выбранное значение должно быть всегда валидным, даже если из списка было убрано значение, соответствующее выбранному (т.е. выбрали 1 и это значение исчезло из списка, value должно стать пустым, а не остаться 1 или еще как-то)


                                1. raveclassic
                                  21.09.2017 00:37
                                  +1

                                  А подробнее можно? Вот верстка:

                                  13 дейтпикеров подряд? Серьезно? Ну будет 13 инстансов компонента дейтпикер, разница то какая?


                                  Потому что ни React, ни Vue еще долго не дотянут до того кол-ва всякой всячины, которая была понаписана для JQuery, а когда будут приближаться, им на смену уже прибежит какой-нить то «Шмеракт»,

                                  Ааа, вы из этих. Сразу б сказали. Под реакт есть все, за исключением тяжелых вещей типа визивигов (хотя есть draftjs) и каких-нибудь навороченных гридов. Под вью не знаю, не работаю с ним.


                                  А вы как будете помнить, какой компонент надо использовать?

                                  А как вы помните какими директивами обмазаться? :)


                                  Да зачем мне это нужно то? Если тот же jquery плагин не делает этого внутри себя, зачем мне это делать? Цель всего лишь сделать jquery реактивным, не более того.

                                  Ну так вас когда спрашивают, какие преимущества ractive перед конкурентами, вы так и отвечайте — никаких, это просто обертка над старушкой jquery.


                                  Ни разу не видел в том же Angular компонента «иконка», а для последователей React это нормально. Такие вещи вообще на стороне css решаться должны, это блин дизайн чистой воды.

                                  Первое что в голову пришло
                                  Часто одним css не решить, и тут трюк в том, что если у вас какая-то навороченная иконка (мало ли) вам не надо бегать по всему маркапу и менять ее везде. Все заинкапсулировано в компоненте <Icon/>.


                                  Что и требовалось доказать))) Так и не понял, откуда взялить всякие там initPlugin, findDOMNode. Почему jquery плагин вдруг стал обладать методом onChange, destroy, resetOnChange и тп.

                                  Представьте, что это абстрактный плагин с данным интерфейсом, и к реакту он не имеет никакого отношения. Хотя, подозреваю, в ractive с абстракциями туго.


                                  При реднаринге вышестоящего компонента, плагин подключается и инициализируется существующим значением, которое может приходить их родительского компонента?

                                  Каюсь, пропустил строку аля this.plugin.setValue(this.props.value); в componentDidMount, но она есть в componentWillReceiveProps.


                                  Когда плагин выполняет свою работу, и пользователь выбирает значение, проперти value обновляется?

                                  Естественно, для этого есть onChange.


                                  Когда другой код (например родительский компонент), обновляет проперти value, плагин понимает что значение изменилось?

                                  Естественно, строка выше в componentWillReceiveProps.


                                  Плагин дает прописать коллбек, чтобы сообщать,
                                  что значение изменилось. Любой другой компонент может получить уведомление об этом изменении?

                                  Какой другой? На каждый инстанс компонента свой инстанс плагина, иначе вы разломаете инкапсуляцию.


                                  Почему jquery плагин инициализируется div'ом,
                                  а не input'ом как в его документации? Внутри функции initPlugin происходит динамическое добавление input в DOM ?

                                  Без разницы. Если у вас плагин для инпута, замените div на input, как бы вы это делали в голом маркапе.


                                  Откуда берутся вспомогательные функции типа initPlugin и findDOMNode? Они глобальные, или импортятся в файл с компонентом?

                                  initPlugin — абстрактная инициализация. Если хотите — $(this.el).customPlugin(), я не хочу углубляться в детали jquery, это не имеет отношения к теме.
                                  findDOMNode — стандартная функция из ReactDOM


                                  Сдается мне вы не до конца поняли задачу. Можете еще написать как данный компонент будет использоваться?

                                  Сдается мне вы не корректно ее поставили. А вот как использоваться —


                                  const instance = <Wrapper value={someValue} onChange={handleValueChange}/>

                                  где value — ваше текущее значение, onChange — обработчик изменения. Данный компонент является controlled компонентом, если нужен uncontrolled — есть HOC.


                                  $$.set('products', $.getJSON('/api/products'));

                                  Ну это ж вообще чушь. Интерфейс должен быть синхронен по отношению к данным. Если у вас данные приходят асинхронно, то в простейшем случае вы это состояние держите в стейте компонента. Странно, у меня поначалу возникло ощущение, что вы знакомы с реактом. А теперь — вообще никак.


                                  Как такое сделать на React?

                                  Да легко


                                  class Foo extends Component {
                                    state = {
                                      products: []
                                    }
                                    componentWillMount() {
                                      $.getJSON('/api/products').then(products => {
                                        this.setState({
                                          products
                                        });
                                      });
                                    }
                                    render() {
                                      return (
                                        <ul>
                                          {this.state.products.map((product, i) => (
                                            <li key={i}>{product.title}, {product.price}</li>
                                          ))}
                                        </ul>
                                      );
                                    }
                                  }

                                  Опять не по условию задачи.

                                  Слушайте, ну это базовые вещи из серии туду-листа


                                  const Select = ({options, onChange, value}) => (
                                    <select value={value} onChange={onChange}>
                                      {options.map(option => (
                                        <option value={option}>{option}</option>
                                      ))}
                                    </select>
                                  );


                                  1. PaulMaly
                                    21.09.2017 02:18

                                    13 дейтпикеров подряд? Серьезно? Ну будет 13 инстансов компонента дейтпикер, разница то какая?

                                    Блин, уже объяснял… ну да ладно.
                                    Под реакт есть все

                                    Очень громко, но я бы поспорил))) Хотя конечно, понаписали и под React не мало всего.
                                    А как вы помните какими директивами обмазаться? :)

                                    Это вы затеяли тему про запоминания, так что не надо передергивать.
                                    Ну так вас когда спрашивают, какие преимущества ractive перед конкурентами, вы так и отвечайте — никаких, это просто обертка над старушкой jquery.

                                    Я такое говорил? Вы спросили, я привел пример. Это лишь пример того, что на том же React делается значительно менее красиво и намного более многословно, что вы и показали вашим кодом.
                                    Часто одним css не решить, и тут трюк в том, что если у вас какая-то навороченная иконка (мало ли) вам не надо бегать по всему маркапу и менять ее везде. Все заинкапсулировано в компоненте <Icon/>.

                                    Ок, маразм крепчает)) В целом я понимаю, что все по-тихоньку к этому привыкают, когда все в одном файле и даже css туда засунем. Через пару лет жду статей на медиуме, типа «как я разочаровался в реакте» или «реакт компоненты это зло». Вот увидите, это случиться.))) Подобные статьи уже итак проскакивают.
                                    Представьте, что это абстрактный плагин с данным интерфейсом, и к реакту он не имеет никакого отношения. Хотя, подозреваю, в ractive с абстракциями туго.

                                    Да уж, Ractive абсолютно конкретен. А какие абстракции дает React интересно?
                                    Каюсь, пропустил строку аля this.plugin.setValue(this.props.value); в componentDidMount, но она есть в componentWillReceiveProps.

                                    Вот именно, все ручками. Бац и забыли мы написать обновлялочку. Постоянные life-cycle хуки и тому подобное, это тоже бесит в реакте. В Ractive тоже есть все эти oninit, onattach, onrender и тп, но когда мне приходится ими пользоваться, я понимаю что спроектировал что-то не так. В Ractive о таких рутинных вещах не приходится думать.
                                    Какой другой? На каждый инстанс компонента свой инстанс плагина, иначе вы разломаете инкапсуляцию.

                                    Я не про инстанс плагина, а про то, чтобы родительский компонент и любой другой компонент могли «послушать» события этого плагина, при этом не вникая в детали реализации и даже не зная, что внутри плагин. Инкапсуляция тут ни при чем, это просто ивенты.
                                    findDOMNode — стандартная функция из ReactDOM

                                    Да, сорян. Давно не юзал и всегда с использованием всего объекта: ReactDOM.findDOMNode().
                                    Ну это ж вообще чушь. Интерфейс должен быть синхронен по отношению к данным. Если у вас данные приходят асинхронно, то в простейшем случае вы это состояние держите в стейте компонента.

                                    Вообще-то у нас интерфейс всегда асинхронен, отсюда и вся мишура с ивентами и тп. Ну это не важно, в моем примере я и держу значение в стейте компонента (проперти products), из него же отрисовываю на экран. Тут же вопрос, как удобно получить отложенное значение в этот самый стейт.
                                    Странно, у меня поначалу возникло ощущение, что вы знакомы с реактом. А теперь — вообще никак.

                                    А с чего вы взяли, что не знаком? То что в реакте так не делается я сказал еще в самом начале.
                                    Да легко

                                    Вы серьезно? Это по вашему легко? Давайте еще раз взглянем. Этот огромный кусок однотипной работы в каждом компоненте, с полностью ручным выставление значения.
                                    class Foo extends Component {
                                      state = {
                                        products: []
                                      }
                                      componentWillMount() {
                                        $.getJSON('/api/products').then(products => {
                                          this.setState({
                                            products
                                          });
                                        });
                                      }
                                      render() {
                                        return (
                                          <ul>
                                            {this.state.products.map((product, i) => (
                                              <li key={i}>{product.title}, {product.price}</li>
                                            ))}
                                          </ul>
                                        );
                                      }
                                    }
                                    

                                    Блин, да так все умеют. Так и на Jquery можно сделать)))
                                    А когда вам нужно будет products запросить с фильтром каким-то вы опять всю эту портянку напишите? Или может в специальную фукнцию обернете? Функция, которая вызывает одну функцию, которая вызывает еще функцию, которая вызывает еще одну функцию)))))

                                    getProductsFromAPI(params) {
                                    $.getJSON('/api/products', params).then(products => {
                                          this.setState({
                                            products
                                          });
                                    }
                                    


                                    Не, лучше в отдельный компонент, как реакт-роутер (то еще чудо человеческой мысли)))

                                    <GetProductsFromApi params={params} component={ShowProducts}/>
                                    


                                    И все это против, одной строки:
                                    $$.set('products', $.getJSON('/api/products'));
                                    

                                    Одной строки, Карл! Какая вам разница асинхронное или синхронное значение выставляется? Разве не фреймверк должен заботиться о такой рутинной операции как разрешение промиса и запись в стейт? Сколько кода просто хломиться вот таким подходом.
                                    Слушайте, ну это базовые вещи из серии туду-листа

                                    Вот именно! Даже такие простые и базовые вещи, которые в Ractive делаются вообще без усилий, бойлерплейта и ручного управления, в React делаются сложно, не удобно, с лишним кодом и отвратительно не красиво. Да вы раскройте глаза и посмотрите насколько это многословно:
                                    // react style
                                    render() {
                                        return (
                                          <ul>
                                            {this.state.products.map((product, i) => (
                                              <li key={i}>{product.title}, {product.price}</li>
                                            ))}
                                          </ul>
                                        );
                                      }
                                    
                                    // ractive style
                                    <ul>
                                    {{#products}}
                                        <li>{{.title}}, {{.price}}</li>
                                    {{/products}}
                                    </ul>
                                    


                                    Чем еще хорош Ractive (кстати в Vue это тоже ценят) в отличии от React, это нормальным js синтаксисом и отсутствием ненужных дополнительных сущностей. Decorator — это просто функция, Adaptor — объект, Transition и Easing — просто функции (о них кстати отдельный разговор), сам Ractive — просто конструктор, конфигурируемый простым объектом, Component — это конструктор, наследуемый от Ractive. Нормальный javascript одним словом и компилить ничего не надо.))))


                                    1. raveclassic
                                      21.09.2017 10:11
                                      +1

                                      Ок, маразм крепчает))

                                      Взаимно :)


                                      А какие абстракции дает React интересно?

                                      Компоненты и компоненты высшего порядка, разумеется.


                                      Бац и забыли мы написать обновлялочку.

                                      Понял, о чем вы. Да, из коробки "реактивности" нет, но в рамках концепции она и не нужна. Компонент — функция props => ui, а пободные пляски нужны только для оберток вокруг jquery, так как вы декларативно спущенные значения императивно напихиваете в несчастный плагин. И этим практически никто не пользуется, так как, как мы уже выяснили, все необходимое уже написано на чистом реакте без таких вот бубнов. В React о таких рутинных вещах не приходится думать.


                                      и любой другой компонент могли «послушать» события этого плагина, при этом не вникая в детали реализации и даже не зная, что внутри плагин. Инкапсуляция тут ни при чем, это просто ивенты.

                                      Ну вы же знаете, какие ивенты будете слушать, они ж не ваши, они плагина.
                                      Пример как пробросить есть — вот onChange же пробрасывается. Если у плагина другой синтаксис подписок, ну, будет, другой синтаксис подписок.


                                      Вообще-то у нас интерфейс всегда асинхронен, отсюда и вся мишура с ивентами и тп. Ну это не важно, в моем примере я и держу значение в стейте компонента (проперти products), из него же отрисовываю на экран. Тут же вопрос, как удобно получить отложенное значение в этот самый стейт.

                                      Интерфейс синхронен по отношению к данным в состоянии, а не к ивентам. Обработка ивентов — это работа с данными (как локальными, так и внешними), а не отображение в интерфейсе.


                                      Вы серьезно? Это по вашему легко? Давайте еще раз взглянем. Этот огромный кусок однотипной работы в каждом компоненте, с полностью ручным выставление значения.

                                      С какой стати вы вообще из ui-слоя аякс-запросы делаете? Надеюсь, вы понимаете, что в реакте так никто не делает? Компонент — синхронная функция от аргументов (пропсов), вот и все. Никаких getJSON, никаких промисов.


                                      А когда вам нужно будет products запросить с фильтром каким-то вы опять всю эту портянку напишите?

                                      Я вообще не запрашиваю данные из компонента, его зона ответственности — отрисовать то, что пришло сверху через пропсы. Если ractive поощряет настолько смешивать слои, ну что уж тут сказать.


                                      Функция, которая вызывает одну функцию, которая вызывает еще функцию, которая вызывает еще одну функцию)))))

                                      Ого, так вы еще и из этих. Каррирование смотрит на вас с удивлением.


                                      Не, лучше в отдельный компонент, как реакт-роутер (то еще чудо человеческой мысли)))

                                      А что не так? Вы видимо с 4 версией не работали. До сих пор храните конфиги роутов сбоку? Тогда мы идем к вам.


                                      Одной строки, Карл! Какая вам разница асинхронное или синхронное значение выставляется? Разве не фреймверк должен заботиться о такой рутинной операции как разрешение промиса и запись в стейт? Сколько кода просто хломиться вот таким подходом.

                                      А если перезапросить?


                                      посмотрите насколько это многословно:

                                      Вы бы для приличия хоть в код вчитались, половину переменных из маркапа можно выкинуть, объявив их выше, и получится практически то же самое.


                                      // ractive style
                                      <ul>
                                      {{#products}}
                                          <li>{{.title}}, {{.price}}</li>
                                      {{/products}}
                                      </ul>

                                      <ul>
                                      {products.map(({title, price}) => (
                                        <li>{title}, {price}</li>
                                      ))}
                                      </ul>

                                      Такое же количество строк Карл! А можете еще скобочки с точками посчитать, я так понимаю, вы любитель :)


                                      это нормальным js синтаксисом

                                      Не смешите, нормальный js вместо косолапых DSL — это фишка Реакта.


                                      компилить ничего не надо.))))

                                      А, вы и из этих тоже.




                                      Мне, на самом деле, уже все понятно по изначальному вопросу про преимущества. :) Что вы тут бессмысленный холивар на совершенно пустом месте разводите — вот это не понятно. Ractive и React — абсолютно разные весовые категории. Для небольших проектов аля что там guardian на нем налабали, обвешавшись jquery-плагинами, наверное самое то. Но для чего-то посерьезней, извините, не возьму.


                                      1. PaulMaly
                                        21.09.2017 13:07
                                        -1

                                        Взаимно :)

                                        То есть для вас CSS в JS это нормально? Похоже это вы их тех… Ну ниче пару лет, медиум, и будете писать другие комменты))) Вокруг все такие не постоянные)))
                                        Компоненты и компоненты высшего порядка, разумеется.

                                        Ну если это по вашему называется абстракциями, тогда в Ractive это тоже есть.
                                        Понял, о чем вы. Да, из коробки «реактивности» нет, но в рамках концепции она и не нужна.

                                        А вы только «в рамках» код писать умеете? Сами то подумать не хотите?
                                        Компонент — функция props => ui, а пободные пляски нужны только для оберток вокруг jquery, так как вы декларативно спущенные значения императивно напихиваете в несчастный плагин. И этим практически никто не пользуется, так как, как мы уже выяснили, все необходимое уже написано на чистом реакте без таких вот бубнов. В React о таких рутинных вещах не приходится думать.

                                        Да что вы привезались к этим декораторам, уже пожалел что привел этот пример. Если у вас «реакт головного мозга» и вы уже не понимаете зачем нужна реактивность, то это ваши проблемы. И хватит уже кичиться кучей компонентов, которые понаписали для вашего реакта. Без них то плюсы есть? Исчезнут все с нуля писать будете?
                                        А если появится супер-мега UI фреймверк на ваниле, вы все его компоненты в реакт-компоненты заворачивать будете?

                                        Пример как пробросить есть — вот onChange же пробрасывается. Если у плагина другой синтаксис подписок, ну, будет, другой синтаксис подписок.

                                        Это те вы так предлагаете пробрасывать, или я не понял:
                                        <Wrapper value={someValue} onChange={handleValueChange} onUpdate={handleValueUpdate} onSomething={handleSomething} onOnemoreTime={handleOnemoreTime}/>
                                        

                                        Серьездно? А если компонент на пару уровней выше хочут «послушать» ивент №100 из плагина, да и вообще из компонента на пару уровней ниже по иерархии, вы тоже пробласывать все через пропсы будете? Вау!
                                        Интерфейс синхронен по отношению к данным в состоянии, а не к ивентам. Обработка ивентов — это работа с данными (как локальными, так и внешними), а не отображение в интерфейсе.

                                        А вы из этих… с реактом в голове которые. Так сказать, в реакте «one-way binding», а у вас «one-way thinking» )))))
                                        С какой стати вы вообще из ui-слоя аякс-запросы делаете? Надеюсь, вы понимаете, что в реакте так никто не делает? Компонент — синхронная функция от аргументов (пропсов), вот и все. Никаких getJSON, никаких промисов.

                                        Я вообще не запрашиваю данные из компонента, его зона ответственности — отрисовать то, что пришло сверху через пропсы. Если ractive поощряет настолько смешивать слои, ну что уж тут сказать.


                                        А вот это вы не из UI сделали? Это как раз прям из UI так из UI, прям из lifecycle хука компонента:
                                          componentWillMount() {
                                            $.getJSON('/api/products').then(products => {
                                              this.setState({
                                                products
                                              });
                                            });
                                          }
                                        

                                        Так даже я, не реактнутый, не делаю:
                                        // вокруг внешний код, не UI
                                        $$.set('products', fetch('/products'))
                                        // вокруг внешний код, не UI
                                        

                                        Давайте пусть будет «сверху», как вы любите:
                                        function getProducts() {
                                              return fetch('/products');
                                        }
                                        <Products list={getProducts}/>
                                        

                                        Так можно сделать? Или придется еще пару компонентов написать?
                                        Еще вопрос, а вы все планируете в componentWillMount запихать? Интересно как быстро он у вас распухает до таких масштабов, что вам приходится компонент дробить?
                                        Ого, так вы еще и из этих. Каррирование смотрит на вас с удивлением.

                                        А причем тут каррирование? Хорошая штука, когда нужна, а когда у вас цепочка функций, единственная цель которых вызвать одну другую функцию, да еще и без необходимости, это извините не каррирование виновато, а руки кривые.
                                        А что не так? Вы видимо с 4 версией не работали. До сих пор храните конфиги роутов сбоку? Тогда мы идем к вам.

                                        Каюсь, нет, это было уже после меня и я рад, что он становиться лучше. Однако глянул в доку бегло:
                                        <BrowserRouter
                                          basename={optionalString}
                                          forceRefresh={optionalBool}
                                          getUserConfirmation={optionalFunc}
                                          keyLength={optionalNumber}
                                        >
                                          <App/>
                                        </BrowserRouter>
                                        <HashRouter>
                                          <App/>
                                        </HashRouter>
                                        <NavLink to="/about">About</NavLink>
                                        

                                        Примерно также кривота, через никому не нужные компоненты-обертки, как и раньше, но за конфиги спасибо конечно.
                                        А если перезапросить?

                                        Хоть сто раз, кака разница то? Вот смотрите:

                                        $$.set('products', getProducts);
                                        $$.set('comments', getComments);
                                        

                                        <MyComponent
                                          products={getProducts}
                                          comments={getComments}
                                        >
                                        

                                        Вот вам какая разница? А ведь getProducts берет данные с сервера, а getComments из localStorage, но блин зачем вам то об этом думать? Вашему компоненту нужны данные, которые он отрисует и все.
                                        Вы бы для приличия хоть в код вчитались, половину переменных из маркапа можно выкинуть, объявив их выше, и получится практически то же самое.

                                        Что значит выкинуть? А их можно выкинуть, те я разве могу это все не писать? Если нет, тогда об чем речь)
                                        Такое же количество строк Карл! А можете еще скобочки с точками посчитать, я так понимаю, вы любитель :)

                                        А вы видимо любитель писать много лишнего кода? Ну сорри, я нет.
                                        Не смешите, нормальный js вместо косолапых DSL — это фишка Реакта.

                                        Шутка года!
                                        А, вы и из этих тоже.

                                        Не знаю из каких, но я собираю проекты webpack'ом c babel, как и все. А шаблоны Ractive заранее прекомпилирую и кладу в бандл. Однако при этом, я могу код и на jsfiddle писать при желании, и в консоле браузера и вообще без nodejs на компе))) Бац!
                                        Для небольших проектов аля что там guardian на нем налабали, обвешавшись jquery-плагинами, наверное самое то. Но для чего-то посерьезней, извините, не возьму.

                                        Да вот пристали вы к этим декораторам и все тут. Я конечно понимаю, что реакт не решает задачи сложнее чем вывод датапикера на эркан, поэтому все остальные мои вопросы вы практически проигнорировали. Давайте тогда вы вот сюда посмотрите, может яснее будет.

                                        Ладно, если вы сами не видите, насколько убогие ваши приверы реализации задач, то я вам тут не помогу.


                                        1. raveclassic
                                          21.09.2017 13:22
                                          +1

                                          То есть для вас CSS в JS это нормально? Похоже это вы их тех… Ну ниче пару лет, медиум, и будете писать другие комменты))) Вокруг все такие не постоянные)))

                                          А что вы сразу на CSS in JS перескакиваете? И, нет, только css-модули. Что там кстати с этим у Ractive?


                                          Ну если это по вашему называется абстракциями, тогда в Ractive это тоже есть.

                                          Ну ка покажите ка мне HOC в Ractive :)


                                          А вы только «в рамках» код писать умеете? Сами то подумать не хотите?

                                          Мм, и зачем мне то, что мне не нужно? Модель построения интерфейса в реакте просто не требует ненужных обвязок вокруг данных вроде их реактивности.


                                          Если у вас «реакт головного мозга» и вы уже не понимаете зачем нужна реактивность, то это ваши проблемы. И хватит уже кичиться кучей компонентов, которые понаписали для вашего реакта. Без них то плюсы есть?

                                          Оп, а вот у вас аргументы то и кончились :) Да, куча плюсов, гранулярность, максимальная переиспользуемость, удобная компонуемость, HOC, вся мощь языка, строгий поток данных и многое другое.


                                          А вы из этих… с реактом в голове которые. Так сказать, в реакте «one-way binding», а у вас «one-way thinking» )))))

                                          Ну если вы любитель кашки в построении интерфейса, то кто я такой, чтобы вас в этом разубеждать?


                                          А причем тут каррирование? Хорошая штука, когда нужна, а когда у вас цепочка функций, единственная цель которых вызвать одну другую функцию, да еще и без необходимости, это извините не каррирование виновато, а руки кривые.

                                          Вы видимо где-то около ходите, но не видите цели каррирования. Это частичное применение и композиция полученных частично примененных функций. То, что вы композицией не пользуетесь, не значит, что больше никто не пользуется. Примеры хоть привели бы. Вангую, будут енхансеры для стора редакса.


                                          Вашему компоненту нужны данные, которые он отрисует и все.

                                          Да, и я вообще не думаю, ни откуда их взять, ни как. Они просто приходят аргументами.


                                          А их можно выкинуть, те я разве могу это все не писать? Если нет, тогда об чем речь)

                                          Ну вы же пишете после маркапа адаптеры. Так и тут, перед возвращением маркапа из рендера вы деструктурируете пропсы.


                                          Шутка года!

                                          Шутка, не шутка, JSX — это JS. Yet another dsl — не JS.


                                          Не знаю из каких, но я собираю проекты webpack'ом c babel, как и все.

                                          Ну так и что вы тогда про компиляцию рассказываете?


                                          Бац!

                                          Бац. Все эти фидлы-шмидлы есть и для бабелей, и для ts, и для чего-угодно.


                                          Давайте тогда вы вот сюда посмотрите, может яснее будет.

                                          Ну и что там? Двусторонний байндинг? Ну так он и не нужен вовсе.


                                          Ладно, если вы сами не видите, насколько убогие ваши приверы реализации задач, то я вам тут не помогу.

                                          Правильно, давайте завязывать, раз уж вы совсем скатываетесь за неимением внятных аргументов. Ок :)


                                          1. PaulMaly
                                            21.09.2017 23:06

                                            А что вы сразу на CSS in JS перескакиваете?

                                            А ну так вы не модный еще просто. Сейчас модно все в JS и стили, и картинки, и шрифты. докер файл? туда же!
                                            И, нет, только css-модули. Что там кстати с этим у Ractive?

                                            О, в Ractive из коробки есть поддержка scoped-стилей для компонентов. Не сказал бы что лучшая реализация, зато без зависимостей и там она была еще тогда, когда CSS Modules и в поминен не было.
                                            Юзаем webpack и стандарный css-loader:
                                            const $$ = new Ractive({
                                                 css: require('./component.css').toString()
                                            });
                                            

                                            Все. Теперь ваши стили в отдельном неймспейсе, а главное без всякой херни типа ICSS и совершенно обычными классами, а не, как там уж пишут:
                                            <div class="${styles.myclass}"></div>
                                            

                                            WAT???
                                            Ну ка покажите ка мне HOC в Ractive :)

                                            Ха-ха! У вас реально реакт головного))) НОС был придуман как костыль под реакт, когда пацаны поняли, что для чуть более сложных вещей реактушка не годится. Начали изворачиваться, зря что ли милионы в маркетинг вбухали))) Ractive поддерживает как композицию, так и наследование компонентов. Нет ничего, что вы можете решить с помощью НОС, чего нельзя решить в Ractive используя просто компоненты. Нам лишние подпорки не нужны.
                                            Мм, и зачем мне то, что мне не нужно? Модель построения интерфейса в реакте просто не требует ненужных обвязок вокруг данных вроде их реактивности.

                                            Если вы уже можете думать только в парадигме реакта, это не значит что так и должно быть.
                                            Оп, а вот у вас аргументы то и кончились :)

                                            У вас они кончились на втором же комментарии. Куча вопросов была вами тупо проигнорирована, поставленные задачи так и не были решены сопоставимым образом и в полном объеме. Дальше начались странные и двухсмысленные подколы. Вас цитирую:
                                            Ааа, вы из этих. Сразу б сказали
                                            Ого, так вы еще и из этих. Каррирование смотрит на вас с удивлением.
                                            А, вы и из этих тоже.

                                            Дальше продолжать? Может это по-вашему аргументы? Кстати, возвращаясь к нераскрытым вопросам. Вот вы пишете:
                                                componentDidMount() {
                                                    this.plugin = initPlugin(findDOMNode(this.el));
                                                    this.plugin.onChange(this.props.onChange);
                                                }
                                            

                                            Я вас спрашиваю:
                                            и любой другой компонент могли «послушать» события этого плагина, при этом не вникая в детали реализации и даже не зная, что внутри плагин. Инкапсуляция тут ни при чем, это просто ивенты.

                                            Вы мне вдруг отвечаете:
                                            Пример как пробросить есть — вот onChange же пробрасывается.

                                            Эм, а вы реально не понимаете разницу между коллбеком, который вы прокидываете в компонент и нормальным ивентом, на который могу подписаться сколько угодно слушателей, в разных частях приложения? Мне говорили, что React — это второй JQuery, но я всегда думал имеется ввиду популярность, ан-нет. Тут вам и components-hell и еще оказывается callback-hell впридачу.
                                            Да, куча плюсов, гранулярность, максимальная переиспользуемость, удобная компонуемость, HOC, вся мощь языка, строгий поток данных и многое другое.

                                            Я вас умоляю, не смешите мои тапки. Так писать как пишут на реакте можно практически везде. Вот глядите, я перепишу компоненты в вашем стиле:
                                            const SelectWithValue = Ractive.extend({
                                              twoway: false,
                                              template: `<div>
                                                            <select value="{{ value }}" on-change="@this.handleChange(@event)">
                                                              {{#options}}
                                                                    <option value="{{ .value }}">{{ .text }}</option>
                                                              {{/options}}
                                            				</select>
                                            				Value: {{ value }}
                                                         </div>`,
                                              data: {
                                                value: '',
                                                options: []
                                              },
                                              handleChange: (e) => {
                                                this.set('value', e.target.value);
                                              }
                                            });
                                            

                                            const Foo = Ractive.extend({
                                              twoway: false,
                                              template: `<ul>
                                            		    {{#products}}
                                            			<li>{{.title}}, {{.price}}</li>
                                            		    {{/products}}
                                                  		</ul>`,
                                              data: {
                                                products: []
                                              },
                                              oninit: (e) => {
                                                $.getJSON('/api/products').then(products => {
                                                  this.set({
                                                    products
                                                  });
                                                });
                                              }
                                            });
                                            

                                            Вот уж умение так умение! Блин, так говнокодить даже на JQuery можно. Что сказать, реакт отличный продолжатель традиций! Вместо кучи jquery плагинов с говнокодом, у нас теперь куча react компонентов с тем же навозом внутри. Реакт умеет подать банальные и примитивные вещи за что-то супер-пупер особенное, не зря маркетологи работают. Фишка в том, уважаемый, что с Ractive я не ограничен писать так код, как требует ситуация или даже как мне нравиться. Я могу писать также как вы, а вот вы на реакте не можете, так как могу я. Кстати, даже в таком убогом стиле, код на Ractive более локоничным получается.
                                            Ну если вы любитель кашки в построении интерфейса, то кто я такой, чтобы вас в этом разубеждать?

                                            Вообще-то это я про ваш стиль мышления писал, который явно на лицо.
                                            Примеры хоть привели бы. Вангую, будут енхансеры для стора редакса.

                                            Вообще-то мы начали с примеров. Читайте тред.
                                            Да, и я вообще не думаю, ни откуда их взять, ни как. Они просто приходят аргументами.

                                            Точно, точно, их вам дед мороз приносит. На санях. Пусть компоненты у вас милашки и работают только с пропсами, но ведь где-то «высоко в горах» вы же ведь пишете обращения к серверу и тп? Ну я не знаю, пусть будет то же самый HOC, типа:
                                             function myHoc(Component) {
                                            
                                               class MyCoolComponent extends React.Component {
                                                state = {
                                                    products: []
                                               };
                                               get = () => $.getJSON('/products').then(products => {
                                                   this.setState({
                                                         products
                                                   });
                                               })
                                              }
                                            }
                                            

                                            Дальше вы этот get прокините куда-нить в компонент.
                                            Блин, но вот вам придется везде, где юзаете промисы писать эту портянку с then -> setState бла бла, неужели не утомляет? Зачем вам это? Разве не лучше так:
                                            
                                               get = () => this.setState({
                                                         products: $.getJSON('/products')
                                                   });
                                            
                                            }
                                            

                                            Или может реакт такое просто не умеет делать, поэтому вы и пытаетесь меня убедить что это все фуфло? Да, думаю так и есть.
                                            Ну вы же пишете после маркапа адаптеры. Так и тут, перед возвращением маркапа из рендера вы деструктурируете пропсы.

                                            Шта? Вы вообще за беседой следите? Адапторы нужны только когда нужно сделать объект произвольного типа (класса) реактивным. Реакт вообще такого не умеет, так что о чем вы говорите.
                                            Шутка, не шутка, JSX — это JS. Yet another dsl — не JS.

                                            Ой, не надо этих сказок.
                                            Ну так и что вы тогда про компиляцию рассказываете?

                                            Все потому что в отличии от вас, для меня она не must-have. Не, вы конечно можете писать и без JSX, но по-моему проще застрелиться.
                                            Бац. Все эти фидлы-шмидлы есть и для бабелей, и для ts, и для чего-угодно.

                                            Наверное уж есть, а вам чей специально искать пришлось )))
                                            Ну и что там? Двусторонний байндинг? Ну так он и не нужен вовсе.

                                            Вы еще и смотрите плохо? )) Там далеко не толко Двусторонний байндинг. А нужен он или нет, это должен решать программист в каждом конкретном случае. В реакте вы этого просто лишены в принципе, поэтому у вас выбора нет.
                                            Правильно, давайте завязывать, раз уж вы совсем скатываетесь за неимением внятных аргументов. Ок :)

                                            Вы бы сперва на вопросы ответили, а то от вас только и слышно:
                                            Ааа, вы из этих. Сразу б сказали
                                            Ого, так вы еще и из этих. Каррирование смотрит на вас с удивлением.
                                            А, вы и из этих тоже.

                                            Вот и вся оргументация.


                                            1. raveclassic
                                              22.09.2017 01:35

                                              Нет ничего, что вы можете решить с помощью НОС, чего нельзя решить в Ractive используя просто компоненты.

                                              В компонент можно передать другой компонент и там его отрендерить?


                                              Нам лишние подпорки не нужны.

                                              ФВП смотрит на вас с удивлением (то же самое). Мир и без наследования прекрасно себя чувствует, учите матчасть, как говорится.


                                              Если вы уже можете думать только в парадигме реакта, это не значит что так и должно быть.

                                              Ну вы схавали реактивность с плагинами, рад за вас, честно. А без них мыслить не можете?


                                              Дальше начались странные и двухсмысленные подколы.
                                              Дальше продолжать? Может это по-вашему аргументы?
                                              Вообще-то это я про ваш стиль мышления писал, который явно на лицо.

                                              Не странные и вовсе не двумысленные, обычные подколы в ответ на глупые выпады :) Но вы продолжайте, продолжайте шатать хабр, это забавно


                                              Вместо кучи jquery плагинов с говнокодом, у нас теперь куча react компонентов с тем же навозом внутри.

                                              Или ractive с кучей говна внутри вдовесок говну на jquery — браво! Ну правда, что за набрасывания :)


                                              Примеры хоть привели бы. Вангую, будут енхансеры для стора редакса.
                                              Вообще-то мы начали с примеров. Читайте тред.

                                              Ну правда, пример в студию где функция, вызывает функцию, вызывающую функцию. Я вам для чайников на пальцах объясню, зачем это.


                                              Эм, а вы реально не понимаете разницу между коллбеком, который вы прокидываете в компонент и нормальным ивентом, на который могу подписаться сколько угодно слушателей, в разных частях приложения?

                                              Ну вы там копайтесь дальше в песочнице со своими ивентами. Где у вас разные куски ui что-то где-то слушают у других кусков ui. Ну правда, jquery головного мозга, перекочевавшее в "реактивность".


                                              Точно, точно, их вам дед мороз приносит. На санях. Пусть компоненты у вас милашки и работают только с пропсами, но ведь где-то «высоко в горах» вы же ведь пишете обращения к серверу и тп?

                                              И в ajax ходите тоже оттуда же. При наличии нормальной архитектуры, а не уровня туду-листа, связь с бэкендом или чем-либо асинхронным у вас будет в другом слое, а не в ui. Учите матчасть, как говорится.


                                              Дальше вы этот get прокините куда-нить в компонент.
                                              Блин, но вот вам придется везде, где юзаете промисы писать эту портянку с then -> setState бла бла, неужели не утомляет? Зачем вам это? Разве не лучше так:

                                              Нет не лучше. Еще раз, вы в упор не видите, что я пишу? Я не использую никаких промисов в ui слое и уж тем более походов за данными, максимум анимации, относящиеся к, тадаам, ui слою.


                                              Или может реакт такое просто не умеет делать, поэтому вы и пытаетесь меня убедить что это все фуфло? Да, думаю так и есть.

                                              Это фуфло, потому что это фуфловый код уровня джуниора, фигачащего запросы в базу из шаблона.


                                              Ой, не надо этих сказок.

                                              Вы что за бред несете. Обратитесь к докам чтоли ради приличия. JSX — это js, тэги — это просто вызовы createElement. А каша из


                                              <div>
                                                              <select value="{{ value }}" on-change="@this.handleChange(@event)">
                                                                {{#options}}
                                                                      <option value="{{ .value }}">{{ .text }}</option>
                                                                {{/options}}
                                                              </select>
                                                              Value: {{ value }}
                                                           </div>

                                              это самая обыкновенная каша на DSL внутри строкового шаблона.


                                              Все потому что в отличии от вас, для меня она не must-have.

                                              Что еще раз говорит об уровне ваших проектов. Вон даже хваленый полимер, который весь из себя такой нативный, без билд-процесса не может. Я уж не говорю про статическую типизацию, без которой на более менее вменяемом проекте никуда.


                                              Вы бы сперва на вопросы ответили, а то от вас только и слышно:

                                              А какие вопросы? Я пока вижу только ваши усердные метания какашек :) И не могу понять, почему. Видимо от обиды, не знаю


                                              Вот и вся оргументация.


                                              1. PaulMaly
                                                22.09.2017 03:01

                                                В компонент можно передать другой компонент и там его отрендерить?

                                                А что вы умеете решать задачи только таким способом? Приводите пример, где вам нужен НОС, а я вам расскажу как сделать без того костыля. А то вы только бла-бла можете, примеров кода от вас дождаться сложно, а на те, что пишете смотерть без слез нельзя.
                                                ФВП смотрит на вас с удивлением (то же самое). Мир и без наследования прекрасно себя чувствует, учите матчасть, как говорится.

                                                И что ФВП? Это что панацея какая-то? Раз он существует, то теперь другие подхода нафиг? Вы там с реактом завязывайте, там можно и загреметь.
                                                Ну вы схавали реактивность с плагинами, рад за вас, честно. А без них мыслить не можете?

                                                Да вы к этим плагинам что пристали то? В основном я пишу чистые Ractive компоненты, иногда оборачиваю либы, написанные на ваниле. Оба вариант значительно удобнее, чем это можно сделать на React.
                                                Или ractive с кучей говна внутри вдовесок говну на jquery — браво! Ну правда, что за набрасывания :)

                                                Причем тут Jquery вообще? ну считайте что это я вам ванильную либу предлагаю использовать. Написанную просто суппер пуппер класно. А еще смотрите-ка ребята из реакта то не разделяют вашу стойкость. С не православным jquery и, о ужас, backbone учат интегрироваться. Видимо только у таких крутых пацанов как вы не бывает таких кейсов.
                                                Ну вы схавали реактивность с плагинами, рад за вас, честно. А без них мыслить не можете?

                                                Я вам последние посты про плагины вообще ничего не говорю, за то вы о них только и думаете. Видимо привыкли на уровне формачек и выпадашек мыслить. Сам Jquery чем-то обидел, что вы так реагируете? Или это комплексы, что на реакте кроме унылых компонентов ничего больше нет?
                                                Ну вы там копайтесь дальше в песочнице со своими ивентами. Где у вас разные куски ui что-то где-то слушают у других кусков ui. Ну правда, jquery головного мозга, перекочевавшее в «реактивность».

                                                Вы похоже больших приложений и не писали в жизни. Ну чтож, не расстраивайтесь. Я понял, что вы молод и наивен в первом же комментарии, про университет))
                                                И в ajax ходите тоже оттуда же. При наличии нормальной архитектуры, а не уровня туду-листа, связь с бэкендом или чем-либо асинхронным у вас будет в другом слое, а не в ui. Учите матчасть, как говорится.

                                                Ой, ну уж вы то мне это рассказывать будете. Может вместо болтавни код покажете, как вы ответы бекенда в ui компоненты передаете. Вместе посмеемся)
                                                Это фуфло, потому что это фуфловый код уровня джуниора, фигачащего запросы в базу из шаблона.

                                                Ничего себе, вы мне прям глаза раскрыли. А теперь читаем мой первый коммент:
                                                Еще пример — хотим писать результат асинхронной операции прямо в реактивную переменную, со всеми вытекающими плюшками (напрямую так делать не хорошо, но мы все равно хотим),

                                                Вам небось лет так 25, не больше. Разработкой то лет 5 хоть занимаетесь? )))) Может уже пора курсы по программирования открывать? ))))
                                                Не странные и вовсе не двумысленные, обычные подколы в ответ на глупые выпады :) Но вы продолжайте, продолжайте шатать хабр, это забавно

                                                Учитывая что вы больше любите теоретический треп и кода от вас не дождешься, то для вас любые выпады глупые. Ведь знаете как говорят — «у кого, что болит». Когда вам кто-то парадигму вашу пошатать хочет, вы сразу в отказ.
                                                JSX — это js, тэги — это просто вызовы createElement.

                                                Прям глаза мне раскрыли))) А я то думал, что это такое в бандле после компиляции. JSX — это такой же новый синтаксис, который надо учить. А на чистых createElement разрабатывать вообще дуба дашь.
                                                это самая обыкновенная каша на DSL внутри строкового шаблона.

                                                DSL или не DSL разница то? Я вообще так написал, чтобы больше на ваш любимый реакт походило. Думал вам понравится, ну типа все тут, все в одном месте. Дурью объединять код и разметку только Реакт додумался заниматься. В Ractive в основном исползуются отдельные файлы шаблонов с нормальным синтаксисом, причем также заранее прикомпиленные.
                                                Что еще раз говорит об уровне ваших проектов. Вон даже хваленый полимер, который весь из себя такой нативный, без билд-процесса не может. Я уж не говорю про статическую типизацию, без которой на более менее вменяемом проекте никуда.

                                                Вы в который раз путаете возможность что-то сделать, с деланием этого. Неужели у вас такое ограниченное сознание? Может тогда к лучшему, что реакт такой примитивный, вы хоть себе в ногу не выстрелите, не даст вам.
                                                А какие вопросы? Я пока вижу только ваши усердные метания какашек :) И не могу понять, почему. Видимо от обиды, не знаю

                                                Ох, ну и тугой же вы. Тогда я сам подведу итоги нашего пари, раз вы в упор не видите моих вопросов, а только какашки вам чудятся (это какой-то знак, без сомнения):
                                                Может ли реакт:
                                                1) обернуть стороннюю любу (для недалеких — не обязательно jquery плагин) удобным и эффективным способом? — нет, не может
                                                2) может ли реакт интегрировать в себя объект произвольного типа (класса) и сделать его реактивным (хотя бы в одну сторону)? — нет, не может
                                                3) Может ли реакт двойное связывание? — нет, не может
                                                4) Может ли реакт точечное обновление DOM? — нет, не может
                                                5) Может ли реакт обойтись без костылей, типа НОС? — нет, не может
                                                6) Реакт что то вообще может? Не выявлено.

                                                Теперь можете вы мне предложить челендж. Покажите «класс» на реакте, чтобы я сказал «вау, я так не смогу»))))


                                    1. indestructable
                                      21.09.2017 13:54

                                      Одной строки, Карл! Какая вам разница асинхронное или синхронное значение выставляется? Разве не фреймверк должен заботиться о такой рутинной операции как разрешение промиса и запись в стейт? Сколько кода просто хломиться вот таким подходом.

                                      А обработка ошибок? А индикатор загрузки? А перезагрузка?


                1. vintage
                  20.09.2017 13:30
                  -2

                  Как будем решать?

                  Нужно two-way:


                  <= Birthday $mol_select
                      value?val <=> birthday?val $mol_time_moment

                  Не нужно two-way:


                  <= Birthday $mol_select
                      value?val <= birthday?val $mol_time_moment

                  Нет проблем, я также признаю что это не безопасная вещь и ее нужно использовать осторожно.

                  Правильное двустороннее связывание вполне безопасно.


                  lazy: true // еще одна прикольная опция, которая работает как для всего инстанса, так и для конкретного инпута

                  В $mol вообще всё ленивое и не требует дополнительной опции.


                  Посмотрел бы я на верстальщиков, которым удобно работать с мелкими кусочками html-подобного «текста» внутри js, вместо нормального html файла без лишнего «шума» и с хорошей подсветкой

                  В хтмл тоже много лишнего шума. Сравните:


                  <!-- куча шума, жёсткий шаблон -->
                  <div class="my-panel">
                      <div class="my-panel-head">
                          {{ head }}
                      </div>
                      <div class="my-panel-body">
                          {{ body }}
                      </div>
                  </div>

                  - ничего лишнего, гибкий шаблон
                  $my_panel $mol_view sub /
                      <= Head $mol_view sub <= head /
                      <= Body $mol_view sub <= body /

                  - хлоп, добавили подвал
                  $my_dialog $my_panel sub /
                      <= Head -
                      <= Body -
                      <= Foot $mol_view sub <= foot /


                  1. PaulMaly
                    20.09.2017 15:44
                    +2

                    В $mol вообще всё ленивое и не требует дополнительной опции.

                    Ну а если я не хочу все ленивое? ;) Или даже, хочу чтобы лишь одно из 100 полей формы было ленивым?
                    В хтмл тоже много лишнего шума. Сравните:

                    Сравнил)) Выглядит отвратительно, да и где вы найдете таких верстальщиков?

                    Послушайте, знает уже весь хабр про ваш mol. Честно говоря он ужасен и не уверен, что кто-то кроме вас его понимает и использует. Здесь мы говорит про более-менее известные фреймверки. И хотя Ractive не является хайповым (что на мой личный взгляд большой плюс), но все же его создавали в The Guardian и на гитхабе 5К звезд, а не 0,1К. Вам безусловно удачи с велосипедом, но лично я бы не перешел с Ractive на mol, без обид.))))


                    1. vintage
                      20.09.2017 16:49
                      -1

                      Ну а если я не хочу все ленивое? ;) Или даже, хочу чтобы лишь одно из 100 полей формы было ленивым?

                      Что за странное желание? Лень — двигатель прогресса.


                      Сравнил)) Выглядит отвратительно,

                      Что конкретно отвратительного?


                      да и где вы найдете таких верстальщиков?

                      Выучили же они как-то куда более сложные языки типа html и css. Со view.tree с его 10 идиомами и подавно разберутся.


                      Честно говоря он ужасен

                      Что конкретно ужасного?


                      и не уверен, что кто-то кроме вас его понимает и использует.

                      Есть такие люди.


                      Послушайте, знает уже весь хабр про ваш mol.
                      Здесь мы говорит про более-менее известные фреймверки.

                      Взаимоисключающие параграфы.


                      все же его создавали в The Guardian

                      И кто такой этот The Guardian? Какие-то большие спецы в программировании?


                      на гитхабе 5К звезд, а не 0,1К

                      А по скорости звёзд с неба не хватает. Вам от числа звёзд на гитхабе теплее становится?


                      лично я бы не перешел с Ractive на mol

                      Почему? Представьте, что он вдруг оказался на хайп-трейне и завтра же набрал 10000 звёзд. Ваши действия? Как будете обосновывать начальству, что Ractive (под который ещё и готовых компонент кот наплакал, так что приходится тащить в проект убогие либы на jQuery) лучше чем $mol (у которого ещё и стандартная библиотека согласованных друг с другом компонент в комплекте)?


                      1. PaulMaly
                        20.09.2017 17:12
                        +1

                        Что за странное желание? Лень — двигатель прогресса.

                        Лично я стараюсь не пользоваться интрументами, которые за меня решают, что мне надо. Гибкость и простота — успех проекта.
                        Выучили же они как-то куда более сложные языки типа html и css. Со view.tree с его 10 идиомами и подавно разберутся.

                        А зачем? Они уже хорошие специ в html/css, вакансий полно, зачем им ваш велосипед, к тому же с таким ужастным синтаксисом (оценочное суждение).
                        Что конкретно отвратительного?

                        Что конкретно ужасного?

                        Это лишь мое «оценочное суждение», но я без отвращения на ваши примеры смотреть не могу. Вы даже JSX утерли, хотя он тоже не красавец.
                        Есть такие люди.

                        Я искрене рад. Всегда обидно, когда твое творчество никому не нужно.
                        Взаимоисключающие параграфы.

                        Аудитория хабра это далеко не аудитория известных фреймверков. Плюс в этом скорее ваша заслуга, чем самого фреймверка. Вы реально во всех темах о нем пишете))))
                        И кто такой этот The Guardian? Какие-то большие спецы в программировании?

                        Ну как бы известное издание, штат программистов я думаю тоже не маленький, аудитория, нагрузка на ресурсы и все такое. А тут вы со своей поделкой)))
                        Почему? Представьте, что он вдруг оказался на хайп-трейне и завтра же набрал 10000 звёзд. Ваши действия? Как будете обосновывать начальству, что Ractive (под который ещё и готовых компонент кот наплакал, так что приходится тащить в проект убогие либы на jQuery) лучше чем $mol (у которого ещё и стандартная библиотека согласованных друг с другом компонент в комплекте)?

                        Ну во-первых, у меня начальства нет) Во-вторых, я же не бегу использовать React, хотя и пробовал и там с готовыми компонентами тоже все норм. Да и практика показывает, что «библиотека согласованных друг с другом компонент в комплекте» приводит к большим проблемам. Юзали мы как-то Quasar для Vue (http://quasar-framework.org/) прям прикольно выглядит все. И компонентов всяких много, и из коробульки всякие там билдеры-шмилдеры, электроны-кардовы, но больше нет, спасибо. )))) Как и всегда в таких случаях — шаг вправо, шаг влево — расстрел.


                        1. vintage
                          20.09.2017 18:26
                          -1

                          Гибкость и простота — успех проекта.

                          Гибкости и простоты в $mol выше крыши. А вот на странные хотелки он не затачивается. Ну или приведите разумный пример, когда ленивость не нужна.


                          А зачем? Они уже хорошие специ в html/css, вакансий полно, зачем им ваш велосипед

                          Чтобы писать меньше, делать больше, и не заставлять бедных программистов без конца нарезать их хтмл-ки с кучей копипасты на шаблоны удобряя логикой.


                          Это лишь мое «оценочное суждение», но я без отвращения на ваши примеры смотреть не могу.

                          Вы точно программист, а не дизайнер? А то чувствуется тонкая душевная организация.


                          Плюс в этом скорее ваша заслуга, чем самого фреймверка. Вы реально во всех темах о нем пишете))))

                          А известные фреймворки стали таковыми сами по себе? Программисты вдруг почувствовали возмущение силы и устремились к ним?


                          Ну как бы известное издание, штат программистов я думаю тоже не маленький,

                          Зачем известному изданию штат программистов?


                          аудитория, нагрузка на ресурсы и все такое

                          Тут и бэкендеры-то не всегда нужны. Что уж говорить про фронтендеров.


                          А тут вы со своей поделкой)))

                          Ну, у нас тоже известная компания, которая куда ближе к написанию софта, чем газета. И что теперь? Вы вообще в состоянии объективно оценивать инструмент, без кивания на попсовость или известность компании-разработчика?


                          React, хотя и пробовал и там с готовыми компонентами тоже все норм

                          Всё норм там лишь с совсем тривиальными компонентами. Компоненты чуть сложнее, чем тривиальные, сделать на Реакте переиспользуемыми и контролируемыми одновременно — смерти подобно.


                          Как и всегда в таких случаях — шаг вправо, шаг влево — расстрел.

                          Я знаю. Именно поэтому $mol не такой. Он позволяет и шаг вправо и влево, и прыгнуть и подползти и вообще любой компонент под полным контролем пользователя.


                          1. PaulMaly
                            20.09.2017 22:38

                            Гибкости и простоты в $mol выше крыши. А вот на странные хотелки он не затачивается. Ну или приведите разумный пример, когда ленивость не нужна.

                            Просто повторю свой тезис — не нужно решать за пользователя. Хотя похоже mol и Ractive вообще в разных лигах играют, потому что Ractive, также как React и Vue, это больше библиотека для UI. Поэтому там нет и не должно быть работы с сетью и других вещей. Если вы играете в большой фреймверк, типа Angular, тогда правила нужны, спорить не буду, все же фреймверк от слова «каркас». Но лично я с фреймверками такого типа завязал.
                            Чтобы писать меньше, делать больше, и не заставлять бедных программистов без конца нарезать их хтмл-ки с кучей копипасты на шаблоны удобряя логикой.

                            Не, так это не работает))) Так что вряд ли. И я, даже пытаться не буду искать людей на подобные вещи.
                            Вы точно программист, а не дизайнер? А то чувствуется тонкая душевная организация.

                            Ну ну, вы хоть читаете комментарии, которые вам люди пишут, когда вы шарманку про mol заводите. Да большая часть комментов все об том же. Так что либо все дизайнеры, либо у вас плохой вкус на синтаксис.
                            А известные фреймворки стали таковыми сами по себе? Программисты вдруг почувствовали возмущение силы и устремились к ним?

                            Тут не могу не согласиться и совершенно не умоляю ваши усилия. Одно это достойно уважения, честно.
                            Тут и бэкендеры-то не всегда нужны. Что уж говорить про фронтендеров.

                            Ну, у нас тоже известная компания, которая куда ближе к написанию софта, чем газета. И что теперь? Вы вообще в состоянии объективно оценивать инструмент, без кивания на попсовость или известность компании-разработчика?

                            Да, давайте оставим это. Ниже я рассписал по пунктам, что лично мне не нравиться в mol. Субъективно, но честно.
                            Всё норм там лишь с совсем тривиальными компонентами. Компоненты чуть сложнее, чем тривиальные, сделать на Реакте переиспользуемыми и контролируемыми одновременно — смерти подобно.

                            Это вам сюда )))) Уважаемый raveclassic утверждает прямо противоположное. Я бы и сам на самом деле посмотрел как у него это получается)))
                            Я знаю. Именно поэтому $mol не такой. Он позволяет и шаг вправо и влево, и прыгнуть и подползти и вообще любой компонент под полным контролем пользователя.

                            Отлично, рад за вас! Но у меня есть Ractive, который позволяет все тоже самое, а может и больше, только без лишних «предположений» и со всеми моими «хотелками»)))


                            1. raveclassic
                              21.09.2017 00:55

                              Раз уж вы меня и сюда призвали, все там норм и с "чуть сложнее, чем тривиальными". А смотреть как "у меня это получается", ну я даже не знаю, походите по гитхабу, посмотрите на сложные вещи. Про количество всяких дейтпикеров и прочих ui-китов я вообще молчу, тысячи их. Да хотя бы вот сюда.


                            1. vintage
                              21.09.2017 09:57

                              Если вы играете в большой фреймверк, типа Angular,

                              Мы играем на более высоком уровне: ExtJS, SAPUI5, VCL.JS и прочие высокоуровневые фреймворки для быстрого построения интерфейсов. Но в отличие от них $mol гораздо более прост, компактен и гибок. Приложения на нём весят меньше, чем на React, который, кроме как рендерить вьюшку ничего не умеет. Во многом это достигается за счёт микромодульности — в бандл не попадает ничего, что вы не используете. Например, для работы с сетью есть стандартный $mol_http с удобным интерфейсом. Если он вам по какой-то причине не подходит — просто не используйте. И мешать он вам никак не будет.


                              Так что либо все дизайнеры, либо у вас плохой вкус на синтаксис.

                              Синтаксис формировался как практичное решение типичных проблем с которыми не справлялся ни html, ни js(on), а не как творческий порыв в приступе желания выпендриться. Я бы не назвал инженером человека, оценивающего результат с точки зрения вкуса, а не качества решения поставленных проблем.


                              Но у меня есть Ractive, который позволяет все тоже самое, а может и больше, только без лишних «предположений» и со всеми моими «хотелками»)))

                              Ractive предоставляет вам ленивый рендеринг из коробки, сквозную эффективную реактивность, непротиворечивое двустороннее связывание, полную абстракцию от асинхронности, статическую проверку корректности кода, набор высокоуровневых компонент, возможность как угодно подстраивать под себя сторонние компоненты (как поведение, так и отображение), автоматическое статическое подтягивание зависимостей по факту их использования, быстрый доступ к компоненту из dom-инспектора, человекопонятные идентификаторы элементов, кроссплатформенность (единое апи для ноды, браузера, кордовы), автоматическое освобождение ресурсов по факту отсутствия зависимости от них, автоматическое логирование изменения всех состояний и прочих интересных штук, возможных именно благодаря "каркасу"?


                              1. raveclassic
                                21.09.2017 10:17

                                Синтаксис формировался как практичное решение типичных проблем с которыми не справлялся ни html, ни js(on)

                                Может напишите об этом? Ну всмысле, какие проблемы были, как решили? Я серьезно


                                Ractive предоставляет вам

                                Зато можно плагинчики инитить без слез


                                1. vintage
                                  21.09.2017 13:07

                                  1. Форсированное разделение програмной логики (где нужна гибкость и мощность языка программирования) и декларативной композиции (где важна простота и наглядность). Никакой дятел не налепит хттп запросов в шаблоне в принципе.
                                  2. Возможность статического анализа взаимоотношений между компонентами. Используется, например, для генерации TypeScript класса (с последующей проверкой корректности TS компилятором), генерации редактора компонента через UI, выноса локализуемых текстов в отдельный файл.
                                  3. Возможность без проблем переопределить любой вложенный компонент извне, не зная о его фактическом местоположении во внутренней иерархии.
                                  4. Гарантия, что у каждого компонента будет уникальное человекопонятное имя (как собственное, так и в контексте компонента-владельца).
                                  5. Наглядное представление потоков данных (стрелочки показывают левостороннее, правосторонне и двустороннее связывание).
                                  6. Минимизация визуального шума — позволяет видеть самую суть.
                                  7. Быстрое и простое создание компонент. Создал файл, написал строчку кода и компонент готов. В каком-нибудь Ангуляре это — целый ритуал, который автоматизируют кодогенератором.
                                  8. Автоматическая простановка БЭМ-атрибутов с поддержкой наследования, и стилизацией подкомпонентов любого уровня без конфликтов.
                                  9. Точечное реактивное обновление DOM без повторного применения всего "шаблона" (из-за чего тормозит треугольник серпинского на Реакте).
                                  10. Возможность не только агрегации компонент, но и наследования.
                                  11. Возможность передавать в свойствах не только строки, но и целые поддеревья.
                                  12. Быстрый доступ к любому подкомпоненту и его дом-элементу через свойство класса.


                                  1. raveclassic
                                    21.09.2017 13:35

                                    1. Годно
                                    2. Чем лучше TSX?
                                    3. Что-то вроде неявного контекста? А хорошо ли это?
                                    4. Не уверен, что могу сказать, хорошо это или плохо
                                    5. Наверное хорошо, когда это действительно потоки, а не один вариант
                                    6. Нууу… Дело привычки, соглашусь
                                    7. А как импорт зависимостей происходит?
                                    8. Вот это уже интересно. В свете 7 вопроса, как происходит разруливание графа зависимостей компонентов для сборки css?
                                    9. А вот это да. Не хватает в реакте
                                    10. Не уверен, хорошо или плохо. Я за композицию все же
                                    11. Вы с обычными строковыми шаблонизаторами сравниваете? Просто у вас написано js(on)
                                    12. Мм это как? Насколько глубоко?


                                    1. vintage
                                      21.09.2017 15:16

                                      Чем лучше TSX?

                                      Чтобы его статически распарсить нужен жен целый TS компилятор. И из полученного AST фиг вычленишь мета-информацию в духе "тут вот у нас двусторонне связывание таких-то свойств, где второе изменяемое и зависит от идентификатора". view.treeже парсится парой небольших библиотек, выдающих самую суть в терминах компонент и свойств, а не в терминах вычисления js кода.


                                      Что-то вроде неявного контекста? А хорошо ли это?

                                      Контекст у нас тоже есть, но тут про переопределение. Можно взять, например, датепикер и сказать ему, что вместо ячеек с датами нужно выводить ссылки:


                                      $my_date_nav $mol_date
                                          Day!id $mol_link
                                              arg * day <= nav_day!id         sub / <= day!id -

                                      Не уверен, что могу сказать, хорошо это или плохо

                                      Это здорово уменьшает бардак творящийся в коде.


                                      А как импорт зависимостей происходит?

                                      Автоматически. Написал в коде $mol_date, как выше — автоматический подцепились:


                                      • класс, реализующий компонент
                                      • стили этого компонента
                                      • переводы текстов для этого компонента
                                      • тесты на этот компонент
                                      • картинки для этого компонента

                                      как происходит разруливание графа зависимостей компонентов для сборки css?

                                      Модули (директории с исходниками) подключаются по зависимостям в соответствии с их приоритетом (приоритеты выуживаются из исходников). В рамках модуля исходники сортируются в порядке увеличения специфичности имени (Например, сначала date.ts, потом date.test.ts). Потом в бандл отбираются исходники соответствующих типов. Таким образом, если $my_date_nav использует $mol_date, то его стили попадут в css-бандл после стилей $mol_date, а значит будут иметь более высокий приоритет при той же специфичности:


                                      [mol_date_day] { ... }
                                      
                                      [my_date_nav_day] { ... }

                                      Не уверен, хорошо или плохо. Я за композицию все же

                                      Не вижу смысла их противопоставлять. Они же для разных вещей предназначены.


                                      Вы с обычными строковыми шаблонизаторами сравниваете? Просто у вас написано js(on)

                                      Тут скорее с X?(HT)?ML сравнение, где поддерево может быть только оно.


                                      Мм это как? Насколько глубоко?

                                      На любой уровень вложенности. Например:


                                      /* Иконка в кнопке добавления аттача на странице детальной информации в приложении по закупкам */
                                      [mol_app_supplies_detail_attach_add_icon] {...}

                                      А в коде этой иконки лишь:


                                      $mol_icon_attach $mol_icon path \M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6h-1.5z


                                1. PaulMaly
                                  21.09.2017 13:17

                                  Зато можно плагинчики инитить без слез

                                  React предоставляет вам… без слез вообще ничего не предоставляет. Все со слезами на глазах ))))) Когда я на нем писал, его блин конфигурироваться надо было, чтобы он хоть рендарил нормально (не знаю как сейчас), а ведь это единственное что он вообще умеет ))))

                                  Ractive предоставляет вам ленивый рендеринг из коробки, сквозную эффективную реактивность, непротиворечивое двустороннее связывание, полную абстракцию от асинхронности, статическую проверку корректности кода, набор высокоуровневых компонент, возможность как угодно подстраивать под себя сторонние компоненты (как поведение, так и отображение), автоматическое статическое подтягивание зависимостей по факту их использования, быстрый доступ к компоненту из dom-инспектора, человекопонятные идентификаторы элементов, кроссплатформенность (единое апи для ноды, браузера, кордовы), автоматическое освобождение ресурсов по факту отсутствия зависимости от них, автоматическое логирование изменения всех состояний и прочи

                                  Вижу вы свой фреймверк любите, это похвально))) Главное что предосталяет мне Ractive — это гибкий и понятный набор возможностей, которые я легко могу расширить и получить «абстракцию от асинхронности» и другие нужные мне вещи (тем что с реактом головного мозга и такие вещи не нужны), а для всяких там типизаций и подтягивания зависимостей, есть другие инструменты.
                                  Мы играем на более высоком уровне: ExtJS, SAPUI5, VCL.JS и прочие высокоуровневые фреймворки для быстрого построения интерфейсов. Но в отличие от них $mol гораздо более прост, компактен и гибок.

                                  А ну тогда говорить в целом не о чем. Как я уже писал, с такими фреймверками я завязал довольно давно. Хотя знаете, вы так его любите, что я наверное тоже гляну на его как будет время поподробнее. С чем черт не шутит. Не понравится, так не понравится, а понравиться — я вам в личку напишу))


                                  1. raveclassic
                                    21.09.2017 13:26

                                    не знаю как сейчас

                                    Стыдоба :) Набрасывать без понимания принципов работы — классика


                                    1. PaulMaly
                                      21.09.2017 16:14

                                      Стыдоба :) Набрасывать без понимания принципов работы — классика

                                      А вы будто знаете Ractive и пробовали его? Классика — это когда «ой мы так не делаем, это не react-way», или вот ваше «у нас этого нет, но нам и не нужно, у нас ведь концепция»!

                                      Это все прекрасно, но только до поры до времени, когда не столкнетесь в более хитрой задачей чем композиция готовых реакт-компонентов. Я то хотя бы пару проектов на React писал, хоть и довольно давно. То что я за ним сейчас не слежу активно, не означает что я не знаю принципов его работы. Знаю и мне они притят. Время от времени посматриваю апдейты — сильно лучше не становиться. Только все больше статей не тему «реакт не торт, теперь у нас Vue (или любой другой новичок)»

                                      Еще раз вам говорю — встретимся на этом же месте через пару лет, посмотрим будете ли вы так любить реакт как сейчас )))


                                      1. raveclassic
                                        21.09.2017 16:25

                                        А вы будто знаете Ractive и пробовали его? Классика — это когда «ой мы так не делаем, это не react-way»

                                        Так я и не набрасываю же, это все вы, микрокомпоненты! нет реактивности! примеры фуфло! Ну и прочие подобные накопившиеся "обиды". Это все от ractive :)


                                        «у нас этого нет, но нам и не нужно, у нас ведь концепция»

                                        Ну а неспособность понять концепцию не говорит, что она не нужна. Точно так же как и не нужны эти ваши кривые плагины.


                                        Это все прекрасно, но только до поры до времени, когда не столкнетесь в более хитрой задачей чем композиция готовых реакт-компонентов. Я то хотя бы пару проектов на React писал, хоть и довольно давно

                                        Ох ты, расскажите мне, желторотому, как большие дяди колбасят энтерпрайз :)


                                        Только все больше статей не тему «реакт не торт, теперь у нас Vue (или любой другой новичок)»

                                        Оценивать мир по статьям это конечно удобно и весело, да


                                        1. PaulMaly
                                          21.09.2017 16:41

                                          Так я и не набрасываю же, это все вы, микрокомпоненты! нет реактивности! примеры фуфло! Ну и прочие подобные накопившиеся «обиды». Это все от ractive :)

                                          Ну так я вам предложил пари, вы согласились. Говрю «можете реализовать это?», а вы мне «могу, но криво». Говорю «а это можете?», а вы мне «могу, но так не надо делать, потому что реакт против» и так далее. Ну а в целом, считаю что реакт сильно испортил фронтенд ((((
                                          Ractive не осилит его «вытащить», так что вся надежда на Vue.
                                          Ну а неспособность понять концепцию не говорит, что она не нужна. Точно так же как и не нужны эти ваши кривые плагины.

                                          Ой, да я вас умоляю. Хватит уже про эти плагины. Вы и половины вещей не сможете сделать на реакте, без костылей и кучи компонентов-оберток. А то что реакт до сих пор не умеет делать точечные изменения данных, это вообще днище.
                                          Ох ты, расскажите мне, желторотому, как большие дяди колбасят энтерпрайз :)

                                          Про энтерпрайз я не писал, хотя реакту делать нечего имхо. Да и на аутсорсе с ним тяжко, особенно когда стэк не под полным контролем.
                                          Оценивать мир по статьям это конечно удобно и весело, да

                                          А вы почему мир оцениваете? По кол-ву реакт компонентов? Ангуляр тоже думал, что будет любим вечно, тоже в свое время ломал концепции и строил свои, а сейчас где он?


                                          1. raveclassic
                                            21.09.2017 16:58

                                            Ну так я вам предложил пари, вы согласились. Говрю «можете реализовать это?», а вы мне «могу, но криво». Говорю «а это можете?», а вы мне «могу, но так не надо делать, потому что реакт против» и так далее. Ну а в целом, считаю что реакт сильно испортил фронтенд ((((

                                            А ЧТО вы там предложили то? Обернуть jquery плагин? Дык они и за бесплатно никому не нужны, конечно будет трудно с ними работать декларативно, потому что они трудные бай дизайн. Курам на смех такие пари.


                                            Вы и половины вещей не сможете сделать на реакте, без костылей и кучи компонентов-оберток.

                                            Что, померяться удумали? Нет уж. Сама идея ходить в jquery за дейтпикерами уже говорит об ущербности ractive не только как движка, а еще и как экосистемы. Так-то кроме связывания этих плагинов несчастных (про которые уже реально хватит) больше "особенностей" не видно.


                                            А вы почему мир оцениваете? По кол-ву реакт компонентов? Ангуляр тоже думал, что будет любим вечно, тоже в свое время ломал концепции и строил свои, а сейчас где он?

                                            Я оцениваю мир по трудозатрам команды на разработку и поддержку тяжелых проектов, а не по статьям с очередными убийцами чего-либо. Из всего по несколько раз опробованного, выигрывает реакт. Не было бы у нас туевой кучи пересекающихся ui-китов в довесок к десятку проектов, а просто разовые приложения, то выиграл бы, скорей всего, ангуляр 2 ибо возни с конфигурацией меньше.


                    1. indestructable
                      21.09.2017 14:01
                      +2

                      Послушайте, знает уже весь хабр про ваш mol. Честно говоря он ужасен и не уверен, что кто-то кроме вас его понимает и использует.

                      Он, похоже, весьма продвинут в плане внутренностей (и там даже есть вещи, которые нельзя реализовать в том же реакте), но синтаксис шаблонов ужасен. Нет, я уверен, что после изучения и подавления изначального впечатления, пользоваться им будет можно и, наверное, даже удобно. Но в том виде, котором он есть — не взлетит.


                      1. vintage
                        21.09.2017 15:23

                        Это и не шаблоны вовсе. От использования шаблонов для композиции компонент давно уже пора отходить, ибо на выходе получаются функции/классы, а никак не HTML.


            1. alexs0ff
              20.09.2017 10:25

              >>Иной раз такие длинющие выражения получаются в тегах.
              Это Bad style в разработке.
              Было (да и щас есть)в Делфях выражение With, которое позволяло определять область видимости для свойств объекта. Ну т.е. пишем не obj.PropertyName, а можем просто ProperyName. Так и хотелось по рукам надавать, кто его использовал это же просто нельзя поддерживать.


              1. PaulMaly
                20.09.2017 10:41

                >>Иной раз такие длинющие выражения получаются в тегах.
                Это Bad style в разработке.

                Это вы о чем? Я вот об этом:
                <option v-for="option in options" v-bind:value="option.value">
                

                Ооочень многословно получается.


                1. alexs0ff
                  20.09.2017 15:22
                  +1

                  Ооочень многословно получается.

                  Ну вот не вижу почти разницы, кроме нарушения в случае с Reactive уровней доступа с объектами. (как я описывал в Делфях конструкцию With)

                  // ractive style 
                  <select value="{{ selected }}">
                      {{#options}}
                      <option value="{{ .value }}">{{ .text }}</option>
                      {{/options}}
                  </select>
                  


                  <select [(ngModel)]="selectedValue">
                      <option *ngFor="let i of list" [ngValue]="i.value">{{i.title}}</option>    
                  </select>
                  


                  1. PaulMaly
                    20.09.2017 15:51

                    Ну вот не вижу почти разницы, кроме нарушения в случае с Reactive уровней доступа с объектами. (как я описывал в Делфях конструкцию With)


                    Где вы тут нарушение увидели? Это же цикл, просто записанный в укороченном виде (лично мне так больше нравиться). Давайте я напишу полный вариант, чтобы было понятно (внимание, options = []):

                    // ractive style 
                    <select value="{{ selected }}">
                        {{#each options}}
                        <option value="{{ this.value }}">{{ this.text }}</option>
                        {{/each}}
                    </select>
                    

                    Так лучше?


                    1. alexs0ff
                      20.09.2017 15:57

                      Так лучше?

                      {{#each options}}
                          <option value="{{ this.value }}">{{this.text }}</option>
                          {{/each}}


                      А если мне нужен будет цикл в цикле и у обоих объектов есть филды value и text? Как написать?


                      1. PaulMaly
                        20.09.2017 16:32

                        А если мне нужен будет цикл в цикле и у обоих объектов есть филды value и text? Как написать?

                        А в чем проблема то? Если же вам нужно иметь доступ к полям элемента вышестоящего цикла во внутреннем, это тоже уже продумано в Ractive:

                        <ol>
                          {{#channels}}
                          <li>
                          	<ul>
                             	{{#epg}}
                           		<li>
                           			<b>Channel Name:{{ ../name }}</b>
                           			<b>Program Name:{{ .name }}</b>
                           		</li>
                             	{{/epg}}
                          	</ul>
                          </li>
                          {{/channels}}
                        </ol>
                        

                        Можете хоть из 10-ти слоев иерархию накрутить и в каждом поля назвать одинаково, и все равно сможете получить к ним доступ. Лично на мой взгляд, достаточно интуйтивно. В Ractive вообще доступ в данных осуществляется с использованием концепции Keypath, в целом похожей на пути. Обычно keypath используются «сверху вниз»:
                        $$.set('products.0.name', 'Coca-Cola');
                        

                        Но как видите можно и в обратном порядке )))


                        1. alexs0ff
                          20.09.2017 16:36
                          +1

                          <b>Channel Name:{{ ../name }}</b>
                             			<b>Program Name:{{ .name }}</b>
                          


                          ../name

                          Совершенно не интуитивно и ведет к багам, т.к. замучаешься считать ././././.
                          В ангуляре мы каждую переменную именуем и производим доступ по имени, которое должно содержать что-то осмысленное.


                          1. PaulMaly
                            20.09.2017 17:27

                            Совершенно не интуитивно и ведет к багам, т.к. замучаешься считать ././././.

                            А, ну так вы бы сразу сказали что вам надо))) Обычно удобнее работать в контексто-зависимой манере, но в Ractive вы можете писать как вам хочется. Вот тот же пример только в вашем стиле:

                            <ol>
                              {{#channels as channel}}
                              <li>
                              	<ul>
                                 	{{#epg as ep}}
                               		<li>
                               			<b>Channel Name:{{ channel.name }}</b>
                               			<b>Program Name:{{ ep.name }}</b>
                               		</li>
                                 	{{/epg}}
                              	</ul>
                              </li>
                              {{/channels}}
                            </ol>
                            


                        1. raveclassic
                          20.09.2017 16:44

                          А если нужно вдруг еще один цикл добавить, а у вас этих ../name 300? А во вложенных тоже ../name?


                          1. PaulMaly
                            20.09.2017 17:35

                            Нет проблем, тогда лучше делать не так, а см. ответ выше. ))))


            1. vintage
              20.09.2017 12:57

              Как-то вы много кода написали, а он не рабочий. Передаёте в датапикер число, а он ожидает Date, в инпут выводите число, а не строку (весёлой отладки без статической типизации), пробрасываете событие, но не вызываете update (не дёргает же фреймворк апдейт при любом событии?).


              Смотрите, та же декорирующая обёртка (хотя тут логичнее было бы полноценный компонент иметь) над датапикером в $mol (хотя, у нас скоро будет свой по круче и по компактней):


              namespace $ {
              
                  /// Объявляем наш декоратор
                  export $my_datepicker extends $mol_ghost {
              
                      /// Реактивное изменяемое свойство для текущей даты
                      @ $mol_mem
                      date( next = new Date ) { return next }
              
                      /// Экземпляр jQuery с инициализированным датапикером
                      @ $mol_mem
                      api() {
                          return jQuery( this.dom_node() ).datepicker({
              
                              /// При выборе меняем текущую дату
                              onSelect : ( val : Date )=> this.date( val )
              
                          })
                      }
              
                      /// При рендеринге устанавливаем в пикер текущую дату
                      render() {
                          this.api().datepicker( 'setDate' , this.date() )
                          super.render()
                      }
              
                      /// При уничтожении уничтожаем и пикер
                      destroyed( next?: boolean ) {
                          if( next ) this.api().datepicker( 'destroy' )
                          return super.destroed( next )
                      }
              
                  }
              
              }

              Еще пример — хотим писать результат асинхронной операции прямо в реактивную переменную, со всеми вытекающими плюшками

              Берём и пишем, безо всяких адаптеров:


              @ $mol_mem
              products() {
                  return $mol_http.resource( '/api/products' ).json() as { title : string }[]
              }

              Или вот, еще двойное связывание.

              Знаете, что будет, если отрендерить туда дофига опшенов и так в каждой ячейке таблицы? Лучше не велосипедить с нативным селектом, а использовать отдельный компонент с ленивым рендерингом:


              <= Color $mol_select
                  value?val <=> color?val     dictionary <= colors *

              А вы что используете в работе? Не хотите устроить пари на эту тему?

              А давайте.


              1. PaulMaly
                20.09.2017 16:19
                +1

                Как-то вы много кода написали, а он не рабочий. Передаёте в датапикер число, а он ожидает Date, в инпут выводите число, а не строку (весёлой отладки без статической типизации)

                О чем вы вообще? Это же псевдо-код))) Да и вообще, откуда вы знаете какой плагин datepicker я «типа» использую и что он ожидает? Смешно даже.
                пробрасываете событие, но не вызываете update (не дёргает же фреймворк апдейт при любом событии?).

                Update чего? О чем вы вообще говорите? У datepicker из пример есть возможность указать callback при изменении даты, мы оттуда «стреляем» событием через инстанс Ractive, чтобы последствии любой вышестоящий код мог подписаться на него знать не зная ни про какие jquery плагины. О каких update вы тут говорите?
                Смотрите, та же декорирующая обёртка

                Да вижу, выглядит также ужасно, как и все в mol, спасибо.
                хотя тут логичнее было бы полноценный компонент иметь

                Нет, не логичнее. Нам сам по себе плагин datepicker нужен только, чтобы компенсировать отстуствие подобного инпута в самом браузере. Когда оно появится, можно смело избавляться и от плагина и от декоратора. Если бы речь шла о каком-то более сложном элементе, с внутренне логикой, состоянием и решающим задачи приложения, тогда да, нужно писать компонент. НО это блин хре*ов инпут, поле для ввода значения, не нужен ему компонент. Касательно того же datepicker, считаю уместным писать компонент например в случае 2-х и более инпутов, которые должны работать совместно. Например виджет выбора периода (from-to), когда 2 инпута должны работать в общей логике. Но даже в это случае, я бы написал декоратор для jquery плагина, а вот логику совместно работы этих 2-х инпутов реализован бы в виде компонента — Period Picker )))))

                Берём и пишем, безо всяких адаптеров:

                Правда? А если без $mol_http.resource? Надо вам axios заюзать, или fetch. Кстати, один раз реализовав (или просто взяв готовый) адаптер промисов, можно его юзать не только для запросов по сети, но и для других асинхроных вещей. Ну ладно, предположим в mol работа с промисами «золотой нитью» проходит сквозь весь фреймверк. А как насчет произвольнного, сложного класса? В Ractive в помощью адапторов можно зареактивить фактически объект любого типа. Лично я даже с роутингом работаю как с реактивной переменной, просто написав адаптор к роутеру. Мне очень удобно:

                $$.set('ctx.pathname', '/products'); // навигируем на другой роут
                $$.observe('ctx.pathname', (val) => {}) // слушаем изменения роута
                

                Можно даже в шаблонах работать с ними (хотя это конечно на любителя):
                {{#if ctx.route('/products/:id') }}
                <product-view></product-view>
                {{ else }}
                <main-view></main-view>
                {{/if}}
                

                Короче делаем все, что умеет реактивная переменная.

                Знаете, что будет, если отрендерить туда дофига опшенов и так в каждой ячейке таблицы? Лучше не велосипедить с нативным селектом, а использовать отдельный компонент с ленивым рендерингом:

                Может и лучше, не спорю. Но это всегда можно сделать, если потребуется.
                А давайте.

                Давайте, только без mol. Он как раз не интересен, по причинам описанным в комментарии выше, без обид.


                1. vintage
                  20.09.2017 17:30
                  -1

                  О чем вы вообще? Это же псевдо-код)))

                  Странно, мне проще было сразу написать работающий компонент, а не "опускать несущественные детали".


                  Да и вообще, откуда вы знаете какой плагин datepicker я «типа» использую и что он ожидает?

                  По API же видно, что это: http://api.jqueryui.com/datepicker/


                  О каких update вы тут говорите?

                  У вас в коде только один апдейт:


                      update: (date) => {
                          $el.datepicker('setDate', date);
                      }

                  И при селекте вы не сохраняете выбранное значение:


                      onSelect: (val) => {
                        $$.fire('datepicker:selected', val); // проксируем любые ивенты, которые поддерживает сам плагин
                      }

                  Да вижу, выглядит также ужасно, как и все в mol, спасибо.

                  Что конкретно вас испугало?


                  Нам сам по себе плагин datepicker нужен только, чтобы компенсировать отстуствие подобного инпута в самом браузере.

                  Этот инпут сам по себе уже и есть компонент. Причём полиморфный — в зависимости от атрибута type он превращается в разные компоненты (можете заглянуть в его shadow dom на досуге). Стандартный инпут — хороший пример как делать не надо. Это должен был быть десяток отдельных компонент.


                  И кастомный датепикер нужен будет в любом случае, ибо:


                  1. Единообразие отображения в разных браузерах (стандартный везде выглядит по разному, а то и вообще отсутствует).
                  2. Улучшенный UX ( стандартный довольно убог).
                  3. Реактивное управление (стандартный совсем не реактивный).
                  4. Скорость (стандартные инпуты в большом количестве тупят).
                  5. Расширяемость (в стандартный фиг чего добавишь, например, как задисейблить праздничные дни?).

                  А если без $mol_http.resource? Надо вам axios заюзать, или fetch.

                  Зачем использовать неудобное апи, когда есть удобное?


                  Ну ладно, предположим в mol работа с промисами «золотой нитью» проходит сквозь весь фреймверк.

                  У нас нет ни одного промиса.


                  А как насчет произвольнного, сложного класса?

                  У нас весь фреймворк состоит из произвольных простых классов.


                  Лично я даже с роутингом работаю как с реактивной переменной, просто написав адаптор к роутеру.

                  Не увидел в вашем коде реактивности — обычный evnt emitter. У нас это выглядит так...


                  Реактивно зависим от параметров в урле:


                  product_id( next? : string ) {
                          return $mol_state_arg.value( 'product' , next )
                  }
                  
                  pages() {
                      return [
                          this.Menu() ,
                          ... this.product_id() ? [ this.Details() ] : []
                      ]
                  }

                  Патчим урл:


                  this.product_id( 'QWERTY123' )

                  Можно даже в шаблонах работать с ними (хотя это конечно на любителя):

                  Вот от таких любителей у нас в "шаблонах" вообще нет никакой логики. Только декларативная композиция компонент.


                  Может и лучше, не спорю. Но это всегда можно сделать, если потребуется.

                  Если вы сразу вынесли это дело в отдельный компонент, то поменять его реализацию — не проблема. Если вы по всему проекту распихали эти нативные опшены, то поменять их везде — тот ещё геморрой.


                  Давайте, только без mol. Он как раз не интересен, по причинам описанным в комментарии выше

                  Вы назвали лишь одну причину — "он ужасен", — что в переводе означает "ой, как не привычно, не хочу вникать". Мне нужен более конкретный фидбек: в чём вы видите в нём недостатки, с какими столкнулись трудностями. Тогда у меня будет понимание что и как надо править. Ну или пойму, что я всё это время шёл в неправильном направлении и надо всё выбрасывать да переписывать на Ractive.


                  1. PaulMaly
                    20.09.2017 22:16

                    Странно, мне проще было сразу написать работающий компонент, а не «опускать несущественные детали».

                    Задача была показать принципы и то как можно сделать. Конкретный плагин и апи не важны.
                    По API же видно, что это: api.jqueryui.com/datepicker

                    Писал апи планига из памяти, видимо воспроизвел из ui, но это не умышлено. Они все примерно одинаковое апи имеют.
                    У вас в коде только один апдейт:

                    И при селекте вы не сохраняете выбранное значение:

                    Обе строчки, которые вы привели — просто колбеки. Ractive сам дергает update, когда значение реактивной переменной было изменено (причем именно изменено). onSelect — это колбек, который дергает плагин, когда было установлено значение, зачем мне что-то в нем сохранять? Плагин сам все сохранил уже, а twoway уже обновил реактивную переменную date. Этот коллбек — это просто способ сообщить об этом внешним наблюдателям, если это необходимо.
                    Этот инпут сам по себе уже и есть компонент. Причём полиморфный — в зависимости от атрибута type он превращается в разные компоненты (можете заглянуть в его shadow dom на досуге). Стандартный инпут — хороший пример как делать не надо. Это должен был быть десяток отдельных компонент.

                    Так и не понял к чему вы это. Критика html элемента input? Зачем она нам здесь? Пишите в профильные организации письма, уверен вас назначат главных архитектором html 6.
                    Зачем использовать неудобное апи, когда есть удобное?

                    Опять вы делаете предположения о том, что удобно, а что не для вашего потенциального юзера. Еще один минус в копилку mol. Удобно не удобно, это мое дело, я хочу и в Ractive я еще и могу.
                    У нас весь фреймворк состоит из произвольных простых классов.

                    Причем тут ваш фреймверк? Я говорю есть произвольный класс, сторонний, не вами написанны, назовем его BlackBox. Он имеет какое-то внутреннее устройство, логику, проперти, методы и тп. Вам надо его сделать реактивным. Чтоб он прям как другие переменные, базовых типов был. Чтобы в шаблонах можно было писать, чтобы автоматически рендарилось все при изменении значений в нем, чтоб слушать эти изменения можно было обсервером и тп. Как вы это сделаете? В Ractive для этого есть адапторы.
                    Не увидел в вашем коде реактивности — обычный evnt emitter. У нас это выглядит так…

                    Хрена се ))) То есть по вашему вот это не реактивность:
                    $$.set('ctx.pathname', '/products/1'); // навигируем на другой роут
                    

                    {{#if ctx.route('/products/:id') }}
                    <product-view id="{{ctx.params.id}}"></product-view>
                    {{ else }}
                    <main-view></main-view>
                    {{/if}}
                    

                    Еще раз, что тут происходит. Мы меняем значение реактивной переменной ctx.pathname на другой роут. Меняется адресная строка (pushState или hashBang это уже в настройках роутера), перерисовывается шаблон и отображается компонент отвечающий за информацию о товаре по id. Все кто «слушает» изменение роута (считай смена страницы) получает уведомление. По вашему это не реактивность?

                    Вот от таких любителей у нас в «шаблонах» вообще нет никакой логики. Только декларативная композиция компонент.

                    Опять решаете за меня. Опять минус в карму mol.
                    Если вы сразу вынесли это дело в отдельный компонент, то поменять его реализацию — не проблема. Если вы по всему проекту распихали эти нативные опшены, то поменять их везде — тот ещё геморрой.

                    Навряд ли кейс, который вы описывали в предыдущем комментарии будет настолько актуален для абсолютно всех опшенов. Скорее это будут отдельные, сильно нагруженные контролы. Так что и проблем переписать их не будет. Ваш же подход попахивает преждевременной оптимизацией.
                    Вы назвали лишь одну причину — «он ужасен», — что в переводе означает «ой, как не привычно, не хочу вникать». Мне нужен более конкретный фидбек: в чём вы видите в нём недостатки, с какими столкнулись трудностями. Тогда у меня будет понимание что и как надо править. Ну или пойму, что я всё это время шёл в неправильном направлении и надо всё выбрасывать да переписывать на Ractive.

                    Честно признаюсь, что первое впечатление от вашего фреймверка портиться из-за синтаксиса. В общем-то как и у любого другого, «встречают по одержке». Однако после нашей не продолжительно переписки я понял, что далеко не только это отвратит меня от его использования. Получается примерно следующий расклад:
                    • Крайне не привычный и не красивый синтаксис и стайлгайд
                    • Тоже самое с шаблонами
                    • Очень много предположений о том, что мне нужно, а что нет. Как нужно писать, а как нет.
                    • Слишком много всего «из коробки». Ваши готовые компоненты, встроенная статическая типизация и тп — это все скорее минусы. А вдруг я например захочу использовать flow, а не ваши типы и JQuery UI а не ваши компоненты.
                    • Не слишком популярный и практически никому не известный. Отзывы с которыми я знаком сугубо негативные. Вскопе с первыми 3-мя пунктами это сразу отворачивает от его использования.

                    Думаю, если мы еще немного побеседуем список может значительно расшириться.


                    1. vintage
                      21.09.2017 12:25

                      Задача была показать принципы и то как можно сделать.

                      Тем не менее показательно, что вам было проще написать псевдокод вместо реального.


                      Плагин сам все сохранил уже, а twoway уже обновил реактивную переменную date.

                      Как-то это слишком неявно и не работает в общем случае. Попробуйте так какие-нибудь яндекс карты подключить.


                      Этот коллбек — это просто способ сообщить об этом внешним наблюдателям, если это необходимо.

                      И если будет 10 свойств — нужно будет кидать 10 событий и потом писать 10 колбэков? Есть концепции по лучше.


                      Так и не понял к чему вы это. Критика html элемента input?

                      Мы же обсуждали вопрос должен ли датапикер быть отдельным компонентом или директивой изменяющей поведение другой конкретной компоненты.


                      Опять вы делаете предположения о том, что удобно, а что не для вашего потенциального юзера.

                      Если вы видите какие-то неудобства — не стесняйтесь об этом сообщить — сделаем удобнее.


                      я хочу

                      Опять какие-то капризы. Вы можете конкретно описать чем вас не устраивает стандартный модуль?


                      и в Ractive я еще и могу.

                      Вы в чём угодно можете. Никакой фреймворк вам не помешает сделать любое непотребство.


                      Чтобы в шаблонах можно было писать, чтобы автоматически рендарилось все при изменении значений в нем, чтоб слушать эти изменения можно было обсервером и тп. Как вы это сделаете? В Ractive для этого есть адапторы.

                      Везде есть адапторы. Это вообще универсальный паттерн. Приведённый выше $my_datepicker — пример такого адаптера, который заменяет сложный нереактивный апи jquery-datepicker, на простой реактивный, состоящий всего из одного мутабельного свойства date.


                      $$.observe('ctx.pathname', (val) => {}) // слушаем изменения роута

                      Вот это — не реактивность. В любом случае реактивность — это не про "обновляем вью при изменении модели", а про "каскадные распространения обновлений". Кстати, вы что за роутер используете? В Ractive же каноничный не завезли. Подозреваю, что у вас сначала обновляется стейт, а потом обновляется адресная строка, что является типичной ошибкой при реализации роутинга, так как нет единого источника истины, что приводит к багам различного размера.


                      Опять решаете за меня. Опять минус в карму mol.

                      $mol не позволяет говнокодить. Плохой, негодный $mol.


                      Скорее это будут отдельные, сильно нагруженные контролы. Так что и проблем переписать их не будет.

                      Разгильдяйство какое-то. Вместо того, чтобы сразу делать хорошо и не иметь проблем, делаем абы как, а потом ещё долго лечим детские болезни тут и там.


                      Ваш же подход попахивает преждевременной оптимизацией.

                      Архитектурная оптимизация не бывает преждевременной, но бывает запоздалой.


                      А вдруг я например захочу использовать flow, а не ваши типы

                      Я бы посмотрел, как вы будете flow к Ractive?


                      и JQuery UI а не ваши компоненты.

                      Вы когда еду себе готовите, ограничиваетесь плитой на кухне или разжигаете костёр по среди комнаты? Вам плоды прогресса показывают, а вы цепляетесь за привычки меззойской эры.


                      Отзывы с которыми я знаком сугубо негативные.

                      Хоть один приведёте отличный от "не читал, но осуждаю"?


                      1. PaulMaly
                        21.09.2017 15:58

                        Тем не менее показательно, что вам было проще написать псевдокод вместо реального.

                        Не передергивайте. Там из псевдокода только jquery плагин, потому что я давно с ними не работал. Когда меня спросили, чем мне Ractive нравится больше чем React, вспомнил сдуру, как бесился интегрируя jquery плагин (аналогов реакт-компонентов не было тогда), вот и написал про декораторы. Зато всех это так зацепило, как будто это прям основная фича(((
                        Как-то это слишком неявно и не работает в общем случае. Попробуйте так какие-нибудь яндекс карты подключить.

                        Что не явного то? Twoway binding так работает. Плагин меняет значение инпута, на инпут заасайнен биндинг. Все как обычно.
                        А какие по-вашему могут быть проблемы с картами?
                        И если будет 10 свойств — нужно будет кидать 10 событий и потом писать 10 колбэков? Есть концепции по лучше.

                        Да можно в Ractive обновлять значения каскадно, что вы привязались то? Не всегда это удобно, хотя когда большая вложенность компонентов, так и делается.
                        Если вы видите какие-то неудобства — не стесняйтесь об этом сообщить — сделаем удобнее.

                        Уже целый список где-то приводил. Вот еще пункт: нет логики в шаблонах. Для меня это капец минус. Знаем, пробовали, лишний код писать не хочется.
                        Опять какие-то капризы. Вы можете конкретно описать чем вас не устраивает стандартный модуль?

                        Ну например тем, что у меня уже написал прекрасный DAO поверх Axios и Rx и я хочу его использовать. mol позволит мне rx-поток в свою реактивную переменную пропихнуть без танцев с бубном?
                        Везде есть адапторы. Это вообще универсальный паттерн. Приведённый выше $my_datepicker — пример такого адаптера, который заменяет сложный нереактивный апи jquery-datepicker, на простой реактивный, состоящий всего из одного мутабельного свойства date.

                        Причем тут паттерн? Я вас спрашиваю, мы можете зареактивить объект произвольного класса? Чтобы он работал также как любые другие значения? Ну например, хочу писать rx-потоки прямо в проперти-компонентов.
                        Вот это — не реактивность. В любом случае реактивность — это не про «обновляем вью при изменении модели», а про «каскадные распространения обновлений».

                        Правда? Весь Rx постоен на обсерверах, это раз. Реактивность — это про пересчет значение при изменении зависимых, это два. Каскадные обновления это не основа, а хорошая техника реактивности и ее все умеют. Может не все, но Ractive точно.
                        Кстати, вы что за роутер используете?

                        Сейчас сапомисный, потому что пытаюсь уйти от концепции роутинга, к концепции контекста.
                        В Ractive же каноничный не завезли.

                        И не надо, потому что можно через адапторы подкрутить любой роутер. Ну и готовых сторонних полно их
                        Подозреваю, что у вас сначала обновляется стейт, а потом обновляется адресная строка, что является типичной ошибкой при реализации роутинга, так как нет единого источника истины, что приводит к багам различного размера.

                        Не подозревайте, это не так. Однако реализации роутера вообще к делу не относиться.
                        $mol не позволяет говнокодить. Плохой, негодный $mol.

                        А что является говнокодом решать будете вы? ну ну
                        Разгильдяйство какое-то. Вместо того, чтобы сразу делать хорошо и не иметь проблем, делаем абы как, а потом ещё долго лечим детские болезни тут и там.

                        Ссылка на localhost это мощно))) Проблем может и не возникнуть. Я вообще не понимаю зачем делать селект на 100500 элементов. Если их так много, это уже автокомплит какой-то. Так что не порите чушь.
                        Архитектурная оптимизация не бывает преждевременной, но бывает запоздалой.

                        Особенно, если запоздала она внутри самого фреймверка))
                        Я бы посмотрел, как вы будете flow к Ractive?

                        О, расскажите пожалуйста в чем же могут возникнуть проблемы?
                        Вы когда еду себе готовите, ограничиваетесь плитой на кухне или разжигаете костёр по среди комнаты? Вам плоды прогресса показывают, а вы цепляетесь за привычки меззойской эры.

                        Я вас умоляю, что за дешевые сравнения. Есть задачи, их надо выполнять, ну не сможете вы написать все возможные плагины, компоненты, модули. Не сможете. Если есть готовые, пусть даже на Jquery, то какая разница? А если забыть про Jquery и просто взять классную либу на ваниле?


                        1. vintage
                          21.09.2017 18:15

                          А какие по-вашему могут быть проблемы с картами?

                          Там нет никакого инпута.


                          нет логики в шаблонах. Для меня это капец минус. Знаем, пробовали, лишний код писать не хочется.

                          Там и не надо писать лишний код. Просто логика пишется отдельно и всё. Если логику писать в шаблонах, то она неизбежно разрастается и приводит к куче копипасты (в лучшем случае куча похожих условий, а как правило — целые блоки похожего, но немного разного кода). Плавали, знаем.


                          Ну вот нашёл кусок по проще на Ангуляре:


                          <div class="bak-assets-panel__group">
                              <button class="btn btn-danger"
                                      ng-if="$ctrl.panelData.status === 1"
                                      ng-click="$ctrl.blockAccount()">Заблокировать
                              </button>
                          
                              <button class="btn btn-success"
                                      ng-if="$ctrl.panelData.status === 0 || $ctrl.panelData.status === 2"
                                      ng-click="$ctrl.activateAccount()">Активировать
                              </button>
                          </div>

                          А бывают и портянки подобного на несколько экранов, так что за логикой фиг уследишь. На $mol мухи отдельно, котлеты отдельно...


                          Описали какие компоненты есть у нас внутри и как мы с ними связаны:


                          <= Blocking_panel $mol_row
                              sub <= blocking_buttons /
                                  <= Block $mol_button_danger
                                      title @ \Block
                                      click?event <=> block?event null
                                  <= Activate $mol_button_minor
                                      title @ \Activate
                                      click?event <=> activate?event null

                          Описали логику, какие компоненты когда видны:


                          blocking_buttons() {
                              switch( this.status() ) {
                                  case 1 : return [ this.Block() ]
                                  case 2 : return [ this.Activate() ]
                                  case 3 : return [ this.Activate() ]
                              }
                          }

                          у меня уже написал прекрасный DAO поверх Axios и Rx

                          На базе Rx ничего путного не сделать.


                          mol позволит мне rx-поток в свою реактивную переменную пропихнуть без танцев с бубном?

                          Ну а в чём проблема?


                          observable.describe( val => this.prop( val ) )

                          Ну или как-то так. Мне не хочется сейчас снова погружаться в это фрп-ад.


                          Каскадные обновления это не основа, а хорошая техника реактивности

                          "Реактивное программирование — парадигма программирования, ориентированная на потоки данных и распространение изменений. Это означает, что должна существовать возможность легко выражать статические и динамические потоки данных, а также то, что нижележащая модель исполнения должна автоматически распространять изменения благодаря потоку данных."


                          и ее все умеют

                          Реакт не умеет. Бэкбон только вручную. Rx распространяет события, а не изменения данных.


                          Не подозревайте, это не так.

                          Вы уверены? Или у вас через трансформер реализация с возвращением старого значения?


                          Ссылка на localhost это мощно)))

                          http://mol.js.org/#path/demo=mol_select_demo_colors


                          Я вообще не понимаю зачем делать селект на 100500 элементов. Если их так много, это уже автокомплит какой-то.

                          Селект позволяет выбрать значение лишь из ограниченного набора (каким бы большим он ни был). Автокомплит позволяет ввести любой текст и подсказывает варианты. Разным задачам — разные контролы.


                          Впрочем, представьте табличку 30x10 состоящую из селектов (типичная админка), в каждом 30 вариантов выбора. Итого, вам нужно отрендерить более 9000 элементов, только чтобы просто показать жалких 300 селектов.


                          О, расскажите пожалуйста в чем же могут возникнуть проблемы?

                          Для начала вам нужно будет покрыть flow-аннотациями весь фреймворк. А такие вещи, как keypath вообще никакой flow проверить не сможет.


              1. PaulMaly
                21.09.2017 00:03

                Смотрите, та же декорирующая обёртка

                Честно-пре-честно, решил вчитаться в ваш код, переборов отвращение от mol. Сразу несколько вещей:

                onSelect : ( val : Date )=> this.date( val )
                

                Мне это не нужно, я этого не хочу. Переменная реактивная, поэтому пусть сама проставляется.

                Тут же, не вижу как вы собираетесь сообщать вышестоящим компонентам о том, что в плагине произошли какие-то «события»? При этом вы конечно же не должны нарушать инкапсуляцию плагина внутри компонента. В моем примере это делалось так:
                // в декораторе
                 $el.datepicker({
                    onSelect: (val) => {
                      $$.fire('datepicker:selected', val); // проксируем любые ивенты, которые поддерживает сам плагин
                    }
                  });
                


                Родительский компонент декоратора (тот внутри которого используется декоратор), теперь обладает новым ивентом и может как сам отслеживать изменения, так и любой другой компонент может слушать этот его ивент, а может просто обсервить саму переменную

                $$.on('datepicker:selected', makeSomeNoice); // с помощью ивента проксируемого из плагина, при этом никто и знать не знает, что внутри плагин jquery
                $$.observe('date', makeSomeNoice); // с помощью обсервера реактивной переменной
                


                        @ $mol_mem
                        date( next = new Date ) { return next }
                ....
                        /// При рендеринге устанавливаем в пикер текущую дату
                        render() {
                            this.api().datepicker( 'setDate' , this.date() )
                            super.render()
                        }
                ....
                
                            return super.destroed( next )
                

                Это вообще все лишний код, который мне не нужен. Я не хочу его писать.

                Так и не понял, каким образом вы обновляете плагин, если компонент сам или какой-то другой компонент обновил переменную date. Плагин ведь перерисуется автоматом? Можете написать пример использования данного компонента?


                1. vintage
                  21.09.2017 13:28

                  Тут же, не вижу как вы собираетесь сообщать вышестоящим компонентам о том, что в плагине произошли какие-то «события»?

                  А никак. Я же написал пример использования:


                  <= Color $mol_select
                      value?val <=> color?val     dictionary <= colors *

                  Экземпляр $mol_select тут не будет у себя хранить никакого состояния. Вместо этого он работать со свойством color компонента владельца. Это очень простая и мощная техника, позволяющая избавиться от 99% событий в пользу потоков данных.


                  Так и не понял, каким образом вы обновляете плагин, если компонент сам или какой-то другой компонент обновил переменную date. Плагин ведь перерисуется автоматом?

                  Разумеется, у нас полная реактивность и автоматическое отслеживание зависимостей. Зависимость меняется — обновляются все состояния, что непосредственно от неё зависят, но никакие более. И так каскадно.


                  Можете написать пример использования данного компонента?

                  $my_app $mol_view sub /
                      <= Birthday_picker $my_datepicker
                          date?val <=> birthday_date?val null
                          Sub <= Birthday_input $mol_string
                              value?val <= birthday_string?val \

                  Ну, это я сделал декоратор, по аналогии с вашим. Лучше, конечно, сделать нормальный компонент, тогда использование будет куда удобней:


                  $my_app $mol_view sub /
                      <= Birthday $my_datepicker
                          date?val <=> birthday?val $mol_time_moment

                  $mol_time_moment — удобный апи для работы со временем.


                  1. PaulMaly
                    21.09.2017 15:29

                    А никак. Я же написал пример использования:

                    Что значит никак? Это часть задачи. Протаскивать поперти сверху вниз почти все фреймверки умеют, и Ractive это умеет лучше многих. Частью задачи является проксирование ивентов jquery плагина в реактивные компоненты. Пока вы с ней не справились.
                    Экземпляр $mol_select тут не будет у себя хранить никакого состояния. Вместо этого он работать со свойством color компонента владельца. Это очень простая и мощная техника, позволяющая избавиться от 99% событий в пользу потоков данных.

                    Еще раз повторяю — этим никого не увидишь, это все умеют.
                    $my_app $mol_view sub /
                    <= Birthday_picker $my_datepicker
                    date?val <=> birthday_date?val null
                    Sub <= Birthday_input $mol_string
                    value?val <= birthday_string?val \

                    Блин, это просто набор букв. (((


                    1. raveclassic
                      21.09.2017 15:45

                      Частью задачи является проксирование ивентов jquery плагина в реактивные компоненты

                      Это не задача, а решение. Причем решение так себе, есть лучше, безопаснее и удобнее.


                      1. PaulMaly
                        21.09.2017 16:06

                        Это не задача, а решение. Причем решение так себе, есть лучше, безопаснее и удобнее.

                        В смысле решение? Нет, это как раз часть задачи. Я в своем примере мог и не делать этого. И без такой штуки связка плагина и компонента работает прекрасно. Более того, даже без этого, можно слушать изменение даты встроенными способами:
                        $$.observe('date', makeSomeNoise);
                        

                        В контексте примера эффект будет такой же как и через проксируемый ивент:
                        $$.on('datepicker:selected', makeSomeNoise);
                        

                        Другое дело, что сторонняя либа (в данном случае плагин), может кидать и другие нужные ивенты, которые не связаны напрямую с данными и их значениями, а значить «слушать» из через обсерверы уже не получится. Поэтому часть задачи показать как можно проксировать такие ивенты.

                        Так что не говорите ерунды. Если вы не сталкивались с подобными задачами, значит вы за пределы микро-мирка микро-компонентов реакта и не выходите никогда.

                        Это хорошо когда работаешь над своим продуктом и можешь полностью контролировать весь стэк, а когда у тебя аутсорсинг, да еще с легаси, то тут без таких вещей не обойтись и ваш реакт проверяли — хлопот с ним иногда больше чем пользы.


                    1. vintage
                      21.09.2017 16:07

                      Что значит никак? Это часть задачи. Протаскивать поперти сверху вниз почти все фреймверки умеют, и Ractive это умеет лучше многих.

                      Там в обе стороны протаскивание. Как я уже сказал, в подавляющем большинстве случаев вам не надо реагировать на события — вы просто связываете данные друг с другом.


                      Еще раз повторяю — этим никого не увидишь, это все умеют.

                      Двусторонние каналы никто, кроме $mol не умеет пока что.


                      Блин, это просто набор букв.

                      Ну это примерно такого вида класс:


                      class $my_app extends $mol_view {
                      
                          @ $mol_mem
                          birthday_date( val = null ) { return val }
                      
                          birthday_string() { return '' }
                      
                          sub() {
                              return [ this.Birthday_picker() ]
                          }
                      
                          @ $mol_mem
                          Birthday_picker() {
                              return $my_datepicker.make({
                                  date : val => this.birthday_date( val )
                                  Sub : ()=> this.Birthday_input()
                              })
                          }
                      
                          @ $mol_mem
                          Birthday_input() {
                              return $mol_string.make({
                                  value : val => this.birthday_string( val )
                              })
                          }
                      
                      }


                      1. PaulMaly
                        21.09.2017 16:32

                        Там в обе стороны протаскивание. Как я уже сказал, в подавляющем большинстве случаев вам не надо реагировать на события — вы просто связываете данные друг с другом.

                        Данные да, но как я писал тут ивенты сторонней либы (в данном случае плагина) могут не быть связанныеми напрямую с данными.
                        Двусторонние каналы никто, кроме $mol не умеет пока что.

                        Мне кажется или вы кидаете ссылки на собственные статьи? Хотя все равно спасибо, с удовольствие почитаю. Кто-то кроме вас про эти каналы слышал вообще? Или вы сами придумываете, сами реализуете в mol и потом говорите, что такого нет ни у кого? )))))

                        Ну и опять же с чего вы взяли что так нельзя реализовать на Ractive? Если я правильно понял, то вся фишка в том, что вы сперва ждете изменение «источника правды», а потом протаскиваете изменение наверх по каскаду компонентов? Если да, то я такое и на Ractive напишу, только зачем))))


                        1. vintage
                          21.09.2017 20:22

                          Данные да, но как я писал тут ивенты сторонней либы (в данном случае плагина) могут не быть связанныеми напрямую с данными.

                          Сами по себе ивенты — тоже данные, так что работа с ними происходит аналогично. Разве что они в конце обычно никуда не сохраняются.


                          Мне кажется или вы кидаете ссылки на собственные статьи?

                          Не просто же так я их писал :-)


                          Или вы сами придумываете, сами реализуете в mol и потом говорите, что такого нет ни у кого?

                          Придумываю, пробую на практике и популяризирую. Вот несколько альтернативных реализаций тех же идей:


                          https://github.com/Riim/cellx
                          https://github.com/zerkalica/lom_atom


                          Если я правильно понял, то вся фишка в том, что вы сперва ждете изменение «источника правды», а потом протаскиваете изменение наверх по каскаду компонентов?

                          Сперва обновление доходит до источника правды, а как только тот изменяется, спускается по дереву зависимостей (которое никак не связано с деревом компонентов), непротиворечиво обновляя зависимые состояния.


                          Если да, то я такое и на Ractive напишу, только зачем

                          Для обеспечения консистентности и гарантии описанных в коде инвариантов. Если вы будете пушить значения в одну переменную из разных мест, то эти разные места очень сложно согласовать друг с другом в общем случае.


                          1. PaulMaly
                            21.09.2017 23:12

                            Сами по себе ивенты — тоже данные, так что работа с ними происходит аналогично. Разве что они в конце обычно никуда не сохраняются.

                            Не, ну предположим. Так как произвользому числу компонентов подписаться на события плагина? Только не уподобляйтесь колеге с реактом плиз, который коллбеки через все слои пробрасывает))
                            Не просто же так я их писал :-)

                            Тогда верю, что ваши идеи реализованы только в mol. Кстати, статьи действительно не плохие. Многие идеи понравились.


                            1. vintage
                              22.09.2017 00:35

                              А зачем произвольному числу компонентов подписываться на событие какого-то там плагина? Обычно подписчик всего один, он изменяет состояние, а дальше уже от состояния все и пляшут. Ну или приведите конкретный пример, где это было бы нужно.


                              1. raveclassic
                                22.09.2017 01:38

                                А зачем произвольному числу компонентов подписываться на событие какого-то там плагина? Обычно подписчик всего один, он изменяет состояние, а дальше уже от состояния все и пляшут.

                                За тем, что так всю жизнь делали в жкверях. $('form#login input[type=password]').change(handleChange) Помним, скорбим


                                1. babylon
                                  22.09.2017 02:23

                                  Возможно имеется ввиду [родительский] контейнер, который слушает и подсматривает за плагинами, а таргетные компоненты пользуются такой "услугой".


                                  1. PaulMaly
                                    22.09.2017 03:19

                                    Возможно имеется ввиду [родительский] контейнер, который слушает и подсматривает за плагинами, а таргетные компоненты пользуются такой «услугой».

                                    В целом верно подмечено. Вариантов довольно много может быть.

                                    В любом случае, сторонняя либа может генерировать уникальные ивенты, сообщать какие-то состояния, которые мы иными способами не сможет трекать. Поэтому игнорировать такую возможность нельзя. Также как нельзя асайниться на то, что только один слушатель захочет получать данную информацию.

                                    Предположения — мать всех ошибок.


                                1. PaulMaly
                                  22.09.2017 03:25

                                  За тем, что так всю жизнь делали в жкверях. $('form#login input[type=password]').change(handleChange) Помним, скорбим

                                  Ну да, а еще до этого мы делали так:

                                  <button onclick="handleClick"></button>
                                  


                                  А «модные» ребята вроде вас кричали, «караул так делать нельзя!». Теперь вы делаете (и я кстати тоже; ) ) так:

                                  <button onClick="this.handleClick"></button>
                                  


                                  И это снова стало нормой.

                                  Да ваш любимый «single file component» вообще в PHP придумали и тогда модные ребята кричали «как круто, разметка и скрипты в одном файле»! А теперь в PHP все больше тяготит к java-style oop, а js повторяет его ошибки.

                                  Мораль такова — модные ребята всегда будут существовать, а собственная голова не только для того, чтобы туда есть.


                              1. PaulMaly
                                22.09.2017 03:13

                                Обычно подписчик всего один, он изменяет состояние, а дальше уже от состояния все и пляшут.

                                Что значит «обычно»? С чего вы вообще это взяли? Что обычно, а что нет, решать должен разработчик. Опять делаете предположения за юзеров? Такс, где мой фейспалм.

                                Вы блин мне напоминаете сейчас, ну типа студента или джуниора на собеседовании. Который не смог решить задачку, а потом жалуется, мол «да кому это вообще надо», «в реальном проекте это не пригодится», «никто так не пишет». Есть задача, я бы не сказал, что это канон, но она вполне конкретная и я постарался объяснить откуда ноги ростут. Вы можете ее решить или нет?


                                1. vintage
                                  22.09.2017 07:45

                                  В грамотной непротиворечивой архитерктуре, где компоненты общаются лишь с "владельцем" и "имуществом" — обычно. Можете привести конкретный разумный пример-опровержение, где бы компонентам приходилось общаться друг с другом не через общего владельца?


            1. lega
              21.09.2017 00:55

              <input as-datepicker="date" value="{{ date }}">

              Зачем тут 2 раза «data»?
              Что делать если нужно пробросить 2 «twoway» значения?, например само значение и формат который может изменится, или 2 даты «from-to».

              Кстати многие прочувстовали и уже отвораичваются от двухстороннего биндинга, это был тренд прошло года.
              Не хотите устроить пари на эту тему?
              Вот изолированный компонент на alight, с разным направлением биндинга, не сложнее. Вот в виде директивы, а это минимальное использование.

              хотим писать результат асинхронной операции прямо в реактивную переменную
              В alight можно сделать ещё интересней, попробуйте сделать аналог на Ractive для сравнения.

              Называется это Декоратором и внутри этой функции можно спокойненько сотворить любые нужные действия.
              Ок, декотраторы на элементы есть, а на текст есть? Пример (описание).


              1. PaulMaly
                21.09.2017 02:50

                Зачем тут 2 раза «data»?

                Можно и без 2 раза, так написал. Первый это параметр в функцию декоратора, второй соответственно выставление значения инпута и биндинг.
                Что делать если нужно пробросить 2 «twoway» значения?, например само значение и формат который может изменится, или 2 даты «from-to».

                Да по всяком можно, можно 2 параметра передать, можно в самом декораторе отслеживать вручную. Тут полная свобода, как хочешь так и пишу, но точно найдешь способ как это сделать лучше всего.
                Кстати многие прочувстовали и уже отвораичваются от двухстороннего биндинга, это был тренд прошло года.

                Да я бы сказал, уже года 3 от двухстороннего отворачиваются) Писал выше, что в Ractive не проблема его выключить как для всего компонента, так и для отдельных полей.
                Вот изолированный компонент на alight, с разным направлением биндинга, не сложнее. Вот в виде директивы, а это минимальное использование.

                А кстати не плохо) Завтра всмотрюсь в код подробнее, но на первый взгляд приятно выглядит.
                В alight можно сделать ещё интересней, попробуйте сделать аналог на Ractive для сравнения.

                ок, завтра попробую, спасибо за челендж! ))
                Ок, декотраторы на элементы есть, а на текст есть? Пример (описание).

                А это не просто реактивное значение? Если я с просони вас правильно понял:

                const $$ = new Ractive({
                    data: {
                    	counter: 0
                    }
                });
                
                setInterval(() => $$.add('counter'), 1000);
                


                <input placeholder="{{ counter * 3 }}"> {{ counter * 1 }} seconds
                



                1. lega
                  21.09.2017 10:18

                  А это не просто реактивное значение?
                  Нет, текстовая директива имеет свои методы и область данных как обычная директива, но результат идет в «текст», так же можно обработать любое текстовое значение, вот ещё пример — перевод текста, без всяких observable/watch элементов.

                  Помимо фичей alight легче в 3 раза (21kb против 60kb), и работает заметно быстрее, тест1 — alight в 2-3 раза быстрее, тест2 alight на 20-50% быстрее (протестировал на свежем chrome).


                  1. PaulMaly
                    21.09.2017 10:47

                    Нет, текстовая директива имеет свои методы и область данных как обычная директива, но результат идет в «текст», так же можно обработать любое текстовое значение, вот ещё пример — перевод текста, без всяких observable/watch элементов.

                    А какая разница, если результат тот же? Пока для меня выглядит как не нужна дополнительная сущность.
                    вот ещё пример — перевод текста, без всяких observable/watch элементов.

                    Можно проще и без текстовых деректив )))

                    const $$ = new Ractive({
                      el: 'body',
                      template: require('./templates/parsed/app'),
                      data: {
                    	lang: 'ru',
                        langs: {
                          'en': {
                            'header': 'Some header',
                            'text': 'Test of translation'
                          },
                          'ru': {
                            'header': 'Какой-то заголовок',
                            'text': 'Тест перевода'
                          },
                          'fr': {
                            'header': 'Certains en-tete',
                            'text': 'Essai de traduction'
                          }
                        }
                      }
                    });
                    

                    {{#langs}}
                      <label>
                        <input type="radio" name="{{ lang }}" value="{{ @key }}" /> {{ @key }}
                      </label> <br/> 
                    {{/langs}}
                    <hr/>  
                    <b>{{ langs[lang].header }}</b> <br/>
                    {{ langs[lang].text }}
                    
                    


                    Помимо фичей alight легче в 3 раза (21kb против 60kb), и работает заметно быстрее, тест1 — alight в 2-3 раза быстрее, тест2 alight на 20-50% быстрее (протестировал на свежем chrome).

                    Согласен, Ractive не самый быстрый, это факт. Хотя edge версия стала примерно в 2 раза быстрее, но честно говоря это практически не заметно в проектах. Писали проект на Vue, которые также считается довольно быстрым, потом его перписали на Ractive. Тормознее не стало)
                    Вес также не играет такой уж огромной роли. Сейчас клиентские скрипты в скопе по несколько метров весят, вот это проблема.


                    1. lega
                      21.09.2017 22:11

                      А какая разница, если результат тот же? Пока для меня выглядит как не нужна дополнительная сущность.


                      Тоже самое говорят jQuery разработчики про фреймворки.
                      Оно может быть очень полезно. Дело в том что многие фреймворки не позволяют контроллировать текстовый биндинг, а дают только забиндить переменную/функцию и все.

                      У меня в одном из проектов есть такое использование:
                      {{#get user.departmentId -> companyId -> name}}

                      т.е. у меня в данных есть ид отдела user.departmentId, и это выражение подгружает с сервера «отдел», далее подгружает «компанию» и выводит ссылку и имя. И для этого достаточно вписать это выражение в html/шаблон.
                      Для аналогичного в других фреймворках идет возня с временными переменными и вызовом сервисов, калбеками, промисами и т.п. Т.е. нужно вручную обрабатывать и сохранять потом во временную переменную.
                      Это один из примеров, в итоге эта фича позволяет упростить и сократить код.


                      1. lega
                        21.09.2017 23:17

                        Хабр съел пример (загрузка по цепочке):

                        <a href="{{#get user.departmentId -> companyId -> link}}">{{#get user.departmentId -> companyId -> name}}</a>
                        


                      1. PaulMaly
                        21.09.2017 23:20

                        У меня в одном из проектов есть такое использование:
                        {{#get user.departmentId -> companyId -> name}}

                        Это все запросы к серверу или что? Выглядит не обычно, даже для меня))) Можете точнее описать пример?


                        1. lega
                          21.09.2017 23:31

                          У меня есть веб-приложение с объектом user == {departmentId: 153, name: 'Linus'}, на сервере «миллион данных» которые нет смысла загружать все.
                          Мне нужно вывести имя и ссылку компании на которую ссылается отдел на которые ссылается user.departmentId.
                          Решение — «это» выражение в шаблоне, которое само подгружает отдел берет ссылку компании, подгружает компанию и вставляет имя и ссылку в нужные места, если идентификаторы меняются, «это вырвжение» само подгржает что нужно и выводит в правильные места. При этом ни строчки кода (только шаблон).

                          А т.к. приложение выводит подобные данные сотнями (загрузка идет пачками, лишнего не грузит) получается большая «экономия» кода — код короче и проще.


              1. PaulMaly
                21.09.2017 10:30

                Посмотрел ваш код, в целом весьма не плохо. Наверное потому что очень похоже и на Vue и на Ractive сразу))

                Пара моментов:

                alight('body', {date: '01/01/2017'});
                

                Ок, а если понадобиться, чтобы начальное значение выставлялось из плагина? Там предположим по-умолчанию стоит текущая дата.
                this.scan();
                

                А можно это не писать? Зачем мне это?

                В примере с декоратором, не увидел как можно уничтожать плагин, когда разметка с ним связанная убирается из DOM. Еще почему-то не выставляется изначальное значение (текущая дата) из плагина.

                В alight можно сделать ещё интересней, попробуйте сделать аналог на Ractive для сравнения.

                Попробовал)))
                Компонент:
                var $$ = new Ractive({
                  el: 'body',
                  template: require('./templates/parsed/app'),
                  adapt: [ require('./adaptors/promise') ],
                  data: {
                    search: 'defunkt',
                    name: ''
                  }
                });
                
                $$.observe('search', (val) => {
                   this.set('name', fetch('https://api.github.com/users/' + val).then((r) => r.json().then((r) => r.name)));
                });
                

                Шаблон:
                <input value="{{ search }}" lazy="500"><br/>
                Name: {{ name || "not selected" }}
                

                Получилось чуть более многословно, но работает также. Регистрацию адаптера можно вынести глобально, для всех компонентов, тогда ее можно убрать в конкретном случае.


                1. lega
                  21.09.2017 21:58

                  А можно это не писать? Зачем мне это?
                  Можно, предпочитаю вручную контроллировать изменения.

                  Получилось чуть более многословно, но работает также.
                  Непонятно как масштабировать, похоже надо под каждую переменную по компоненте писать.


                  1. PaulMaly
                    21.09.2017 23:27

                    Можно, предпочитаю вручную контроллировать изменения.

                    А что конкретно вы тут контролируете? Вроде просто функцию вызываете.
                    Непонятно как масштабировать, похоже надо под каждую переменную по компоненте писать.

                    Это точная копия вашего примера. Напишите как можно ваш масштабировать и я напишу тоже самое на Ractive.


                    1. lega
                      22.09.2017 00:10

                      я напишу тоже самое на Ractive.
                      Вот, 2е ф-ии, используются 2 раза с разными входнми параметрами.

                      А что конкретно вы тут контролируете?
                      Тут одним коментарем не описать, в кратце — очень похоже на простой шаблонизатор, «данные» — это просто словарь/объект: var data = {name: 'linux'}; он так и остается простым объектом, алайте его не изменяет. Вы просто указываете что его нужно отрендерить, и он точечно обновляет DOM:
                      var data = {name: 'linux'};
                      var render = alight(element, data);
                      data.name = 'new name';
                      render.redraw(); // scan()

                      Вообщем это как шаблонизтор на стеройдах. scan можно не вызывать если подключить zone.js


              1. PaulMaly
                21.09.2017 12:14

                Ок, теперь давайте я свою вопросы задам:

                1) Можно ли зареактивить объект произвольного класса? В моих примерах упоминались Promise и класс роутера. С промисами все думаю ясно, вот пример использования реактивного роутера:

                // совершенно обычный компонент
                const $$ = new Ractive({
                  el: 'body',
                  template: require('./templates/parsed/app'),
                  adapt: [ require('./adaptors/context') ],
                  data: {
                    ctx: null
                  }
                });
                

                Для себя называю это контекстом, потому что пытаюсь сменить парадигму, но по сути это роутер.

                Реализация роутера не важна, суть в том, что при изменении роута он выставляет текущий роут (ctx) в реактивную переменную ctx. сам роут может быть сложным классом, с методами и тп
                someRouter((ctx) => $$.set('ctx', ctx));
                

                Перейти на другую страницу можно так. со всеми вытекающими плушками реактивности: меняется URL, меняются шаблоны, срабатывают обсерверы и тд
                $$.set('ctx.pathname', '/products/1');
                

                Можем прям в шаблонах менять компоненты в зависимости от роута или других параметров конекста. обратите внимание значение матчится по роуту, параметры парсятся и тп
                {{#if ctx.route('/products/:id') }}
                <product-page-component productId="{{ ctx.params.id }}"></product-page-component>
                {{else}}
                <main-page-component></main-page-component>
                {{/if}}
                

                Используемый мною роутер умеет pushState и hashBang, а также при желании может сам отливливать клики на валидных ссылках. нажатие на ссылку приведен к желаемому результату без лишних усилий
                <a href="/products/1">Product 1</a>
                

                Причем сам роутер не писался по Ractive и его собственный код никак не адаптировался. Это просто удобный роутер с гитхаба.

                2) Есть ли SSR «из коробки»? Вообще насколько просто писать изоморфные (универсальные) приложения на alight? Пример в Ractive:
                // получаем готовый html компонента и всех подкомпонентов
                $$.toHTML();
                // получаем скоупед css (аля shadow dom, только примитивным способом) компонента
                $$.toCSS();
                // получаем весь css всех компонентов
                Ractive.getCSS();
                


                3) Как обстоят дела с анимациями? К примеру, возьмем анимации перехода между экранами(страницами/компонентами/как не назови). Пример Transition в Ractive:
                // регистрируем анимации перехода
                const $$ = new Ractive({
                  transitions: {
                        fade: require('./transitions/fade'),
                	pushHorizontal: require('./transitions/pushHorizontal')
                  }
                });
                

                Усовершенствуем тот же пример, чтобы при клике на ссылку не только показывалась страница товара по id, но и пердыдущая страница скрывалась с анимацией перехода fade-out, а новая страница показывалась с анимацией перехода pushHorizontal-in
                {{#if ctx.route('/products/:id') }}
                <product-page-component id="{{ ctx.params.id }}" pushHorizontal-in></product-page-component>
                {{else}}
                <main-page-component fade-out></main-page-component>
                {{/if}}
                <a href="/products/1">Product 1</a>
                

                Сам Transition — это просто функция, которая принимает несколько параметров.

                4) Можно ли распарсить шаблоны alight заранее, например во вермя сборки и включить в бандл уже готовый AST?
                Ractive.parse(require('./templates/app'))
                


                5) Можно ли прилинковать реактивное значение к другому произвольному значению, например элементу произвольного индекса из массива? Бывает крайне полезно, чтобы ссылаться на выбранный элемент какого-то списка:
                $$.link( 'some.nested.0.list.25.item', 'current' );
                $$.set( 'current.name', 'Rich' );
                


                В целом alight весьма не плох! Очень инетесно узнать как на нем решаются все эти вопросы.


                1. lega
                  21.09.2017 22:50

                  вот пример использования реактивного роутера:
                  Можно сделать по всякому, вот пример роутера основанного, кажется, на идее роутера от реакта
                  Примеры в тут комментах github.com/lega911/angular-light/issues/137#issuecomment-188085346
                  plunkr, plnkr.co/edit/HpUDXdTJ0QFenprkE5QJ?p=preview

                  Помимо этого я ещё реализовывал 3 вида роутеров, под разные проекты разные типы роутеров. Например при переходе на новую «страницу», старая страница не закрывалась, а всплывала табом, и можно было вернуться в любой момент, вообще роутеры — тема не сложная и в готовых всегда что-то не то.

                  Можем прям в шаблонах менять компоненты
                  Вы так описываете как-будто это что-то крутое, вообще на alight можно запилить препроцессор и шаблоны от Ractiv'a будут работать на alight. Я ещё один раз маскировал alight под другой фреймворк, это просто показатель гибкости.

                  > 2) Есть ли SSR «из коробки»?

                  Специального ничего нет, но можно запускать на сервере и сбрасывать в HTML. Я не сторонник SSR.
                  3) Как обстоят дела с анимациями?
                  angularlight.org/doc/examples.html#search=animate
                  Вот примеры с анимацией, есть модуль (для старой версии) для анимации совместимый с анимациями angular 1.4+ (можно просто брать css анимации от ангуляра).
                  Но я его не обновляю т.к. (почти) никому это не нужно, лично мне хватает стандартной манипуляции с css3, в текущем моем проекте анимация есть только в однм месте, да и то не нужна, добавил для прикола.

                  4) Можно ли распарсить шаблоны alight заранее, например во вермя сборки и включить в бандл уже готовый AST?
                  Зачем?
                  5) Можно ли прилинковать реактивное значение к другому произвольному значению,
                  Вот тут как раз alight проще и более гибок, т.к. под капотом dirty-checking так же как и у Ангуляров. Можно отслеживать любые выражения, можно отслеживать любые объекты, попробуйте забиндистя на проперти html элменета или readonly значение котое лежит в модели vue.js (другого фреймворка), Ractive не сможет, а тут нет ограничений. + alight не портит* данные в отличие от, например, vue.js который все подменяет пропертями, тут не нужно создавать compound объекты что бы отслежтвать что-то сложное т.д. И кстати это заблуждение, что dirty-checking медленный, angular и alight идут в топе по тестам.


                  1. PaulMaly
                    21.09.2017 23:44

                    Можно сделать по всякому, вот пример роутера основанного, кажется, на идее роутера от реакта

                    Не, ну реакт роутер это прям вообще не то. Шлак редкостный. Я же вам говорю прежде всего про то, как можно сделать объект произвольного типа (класса) реактивным и работать с ним в Ractive как с любой другой реактивной переменной. Ну давайте другой пример — хочу Rx-поток интегрировать в реактивную переменную alight, для этого есть инструменты?
                    Например при переходе на новую «страницу», старая страница не закрывалась, а всплывала табом, и можно было вернуться в любой момент

                    Вот именно поэтому я ухожу от понятия «роутинга» к понятию «контекст». Этот вариант позволяет гараздо более гибко подходить к вопросам навигации и стейта страницы.
                    Вы так описываете как-будто это что-то крутое,

                    Ну так вы так и не привели пример, как можно зареактивить какой-то произвольный класс. Посмотрел ссылку с роутером:
                    <div al-route="/users/:id"></div>
                    <div al-route="/users/:id/social"></div>
                    <div al-route="/users/detail/:id/edit"></div>
                    

                    Это прям очень на реакт роутер похоже, но ведь это не то. Зачем вообще директива? Говорю же, хочу работать как с любой другой переменной и иметь все те же возможности. Опять же, используя подобную директиву, как сделать более сложное условие, типа:
                    {{#if ctx.route('/modal') && ctx.query.id || someOtherVar}}
                    <modal></modal>
                    {{/if}}
                    

                    Как видите, я волен не завязывать отображение только на роуты. Так как это лишь реактивная переменная, то я могу использовать и другие условия, чтобы показывать один и тот же контент.

                    Специального ничего нет, но можно запускать на сервере и сбрасывать в HTML. Я не сторонник SSR.

                    Тут мы с вами сильно расходимся. Я дикий сторонник)))
                    Вот примеры с анимацией,

                    Что-то дока прям никакая. Можете переписать мой пример на alight?
                    Зачем?

                    Очевидно, чтобы не заниматься этим на клиенте? )))) Так по-любому быстрее и эффективнее получается.

                    Можно отслеживать любые выражения, можно отслеживать любые объекты, попробуйте забиндистя на проперти html элменета или readonly значение котое лежит в модели vue.js

                    Можете пример плиз? У нас вами не совсем одинаковая терминология, поэтому без примеров не всегда понятно.

                    + alight не портит* данные в отличие от, например, vue.js который все подменяет пропертями

                    Кстати, тут я с вами согласен. Мне это в Vue тоже не нравится. Благо Ractive полностью отказался от опции «magic» и теперь все делается исключительно через понятные геттеры-сеттеры.


                    1. lega
                      22.09.2017 00:55

                      объект произвольного типа (класса) реактивным, хочу Rx-поток интегрировать в реактивную переменную, как можно зареактивить какой-то произвольный класс
                      Ничего не понял, набросал мини роутер-пример, как можно легко выводить нужные блоки по роуту и условиям: jsfiddle.net/lega911/dagk05wb

                      Так по-любому быстрее и эффективнее получается.
                      Ну это надо ещё померять, большой кусок DOM строиться быстрее если вставлять целиком в innerHTML, чем собирать по элементам.


              1. PaulMaly
                21.09.2017 19:24

                Вот еще интересный вопрос:

                Есть в нас компонент, допустим ListView. Он довльно навороченный, умеет всякие там селект, фокус, клавиши, какой-нить кастомный скролл, да еще и оптимизированный. Не важно, короче много логики. На вход получает массив айтемов:

                <list-view items="{{ products }}"></list-view>
                

                Шаблон самого компонента примерно такой:
                <ul>
                {{#items}}
                    <li></li>
                {{/items}}
                </ul>
                

                Пока все понятно, но суть задачи в том, что мы хотим использовать этот компонент для разного вида списков. Списки будут отличаться во-первых данными, во-вторых разметкой айтемов. При этом каждый отдельный айтем не имеет своей логики. Вся логика внутри компонента ListView. Отличаются только структура данных и разметка.

                Вангую, что ребята из React начнут неистово колбасить компоненты под каждый вариант айтема. До тех пор пока клавиатура не задымиться. ))) Представляете, куча дополнительных компонентов только для того, чтобы отрендерить пару тегов)))))

                Решение на Ractive как всегда крайне локонично. Шаблон компонента будет выглядить так:
                <ul>
                {{#items}}
                    <li>{{>content}}</li>
                {{/items}}
                </ul>
                


                Да еще момент, так как данные разные, например список товаров и список юзеров, то хотелось бы чтобы при использовании эти списки тоже семантичеки отличались. Теперь использование:

                const ListView = require('./components/listview');
                const $$ = new Ractive({
                    components: {
                         users: ListView,
                         products: ListView
                    },
                    data: {
                         users: [],
                         products: []
                    }
                });
                

                <users items="{{users}}">
                     <img src="{{ .avatar }}">{{ .name }} ( {{ .rating }} )
                </users>
                <products items="{{products}}">
                     <img src="{{ .photo }}">{{ .title }} - {{ .price }} {{ .currency}}
                </products>
                


                Хотелось бы узнать как это решается в alight?


                1. lega
                  21.09.2017 23:01

                  Без проблем, вот тут есть переписка с примерами. Я просто взял пример для Angular 2 (порядка 300-400 строк кода) и переписал на alight в 28 строк с теми же шаблонами.

                  PS: извиняюсь за «напористость», уж очень много тут текста и комментов, читать не удобно.


                  1. PaulMaly
                    21.09.2017 23:49

                    Без проблем, вот тут есть переписка с примерами.

                    Посмотрел вот этот пример. В целом да, зачет.

                    Однако, даже если убрать доволнительную логику самого компонента, получается все равно не так элегантно ))) Хотя на вкус и цвет конечно…

                    А, ну еще не раскрыт подвопрос, как сделать симантически красиво:
                    Да еще момент, так как данные разные, например список товаров и список юзеров, то хотелось бы чтобы при использовании эти списки тоже семантичеки отличались.

                    Проще говоря — один компонент, а названия тегов в зависимости от контекста.


                1. raveclassic
                  22.09.2017 01:42

                  Вангую, что ребята из React начнут неистово колбасить компоненты под каждый вариант айтема. До тех пор пока клавиатура не задымиться. ))) Представляете, куча дополнительных компонентов только для того, чтобы отрендерить пару тегов)))))

                  HOC улыбаются и машут вам ручкой :)


                  const List = ({Item, items}) => (
                    <ul>
                      {items.map(item => <Item>{item}</Item>)}
                    </ul>
                  )

                  Я прям on-the-fly без дополнительной конфигурации


                  1. PaulMaly
                    22.09.2017 03:07

                    HOC улыбаются и машут вам ручкой :)

                    Вау, вот это да!!! Как круто!!!

                    Хотя нет, один момент… а не хотите раскрыть что такое:

                    <Item>{item}</Item>
                    


                    Ну и еще пару вариантов использования в разной разметкой айтема и разным именованием тегов в шаблоне, приведите пожалуйста.

                    Понимаю, как всегда вопрос не уложился в вашу парадигму и вы его не поняли. Не расстраивайтесь.


                    1. vintage
                      22.09.2017 08:00

                      Реальный код выглядел бы так:


                      const List = ({ list_props = {} , Item, items_props = [] }) => (
                        <ul ...list_props>
                          {items_props.map(item_props => <Item ...( item_props || {} ) />)}
                        </ul>
                      )

                      const App = () => (
                        <List Item="li" items_props={ products.map(product => [{
                            className="product"
                            children=[ ... ]
                        }]) } />
                      )

                      Компонент-то лаконичный, но использовать его неудобно.


  1. raveclassic
    20.09.2017 01:21

    del


  1. KoToSveen
    20.09.2017 04:36
    -1

    «Чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки.»
    Взято тут.


  1. Zaruki
    21.09.2017 14:21

    Вообще-то еще есть Ember JS. Странно что его нет в обзоре