Почему вам НЕ стоит использовать AngularJs

    Много времени прошло с момента появления AngularJs (в масштабах веб-технологий конечно). Сейчас в интернетах есть огромное количество постов восхваляющих этот фреймворк до небес, что это манна небесная не иначе, а критики не так уж и много как он того заслуживает. Но такие статьи уже потихоньку начинают появляться, и меня это радует, надеюсь индустрия переболеет ангуляром так же, как переболела MooTools, Prototype, %какой-нибудь новый язык под JVM%, %другая-супер-революционная-технология%. Не знаю почему, но в IT-области такие революционные технологии, которые поднимают шум, а потом пропадают, появляются довольно часто. Хороший разработчик должен уметь отличать очередную модную технологию, от работающего инструмента. И для этого очень важно критически смотреть на вещи. Моя статья — это компиляция самых весомых выводов из других статей, и моих личных умозаключений. Ангуляр создает хороший вау-эффект, когда видишь его впервые: «ух ты, я написал ng-repeat, и реализовал эту логику одними тегами и все само обновляется!», но как только приходится реализовывать реальные приложения, а не очередной TODO-лист, то все становиться очень печально. Сразу хочу сказать, что фреймворк я знаю хорошо, даже больше чем мне хотелось бы его знать, я программировал на нем в течении 2 лет. И для следующего проекта я его точно не выберу, и это хорошо, все мы учимся на ошибках. Так что же не так с ангуляром? Тут нет однозначного ответа, слишком много разных недостатков, которые создают такой облик фреймворку. Если одним словом – непродуманная архитектура. Под катом я привожу конкретику, так что устраивайтесь поудобнее. ДА НАЧНЕТСЯ ХОЛЛИ ВАР!

    Двусторонний дата-биндинг


    Существует фундаментальное правило программирования, оно относиться к совершенно любому языку или технологии, это правило гласит — явное лучше неявного. Все эти watcher'ы это неявный вызов обработчиков событий. В реальности события происходят при клике по элементу, а не при изменении данных, поэтому когда вы пишите на ангулярке вам необходимо думать следующим образом: «ага, тут кликнули по кнопке и изменилась модель, теперь нужно слушать изменения на этой модели и когда она меняется вызывается хэндлер», а не «кликнули на кнопку, вызвался хэндлер», ДВУСТОРОННИЙ БИНДИНГ — ЭТО НЕ ТО КАК ПРОИСХОДИТ ОБРАБОТКА СОБЫТИЙ В ПРИНЦИПЕ. Это тоже самое, что вы достаете данные из базы данных и записываете их в модель, и только на изменениях модели вызываются колбэки, да так вообще нигде не реализовано, даже на Java, язык который вообще не имеет анонимных функций (когда я на нем еще писал), реализовывал колбэки на классах. Потому что это явно, потому что такая концепция описывает реальное положение вещей. Даже будущая версия Ember.js не будет использовать двусторонний дата-биндинг.

    Еще двусторонний биндинг означает, что изменив что-либо в своем приложении, это тригерит сотни функций, которые наблюдают за изменениями. И это чудовищно медленная операция, особенно все становится плохо на мобильных платформах. И это фундаментальная часть фреймворка. Ангуляр даже накладывает ограничения на то насколько богатый UI можно писать. И что самое интересное, это не какое-то эфемерное и далекое ограничение в которое вы никогда не упретесь. Это всего лишь 2000 биндингов, и если вы разрабатываете более-менее большое приложение, ТО ВЫ ТОЧНО УПРЕТЕСЬ В ЭТО ОГРАНИЧЕНИЕ. И тут вам придется драться с фреймворком. Ангуляр вводит возможность одностороннего дата-биндинга, что бы избежать проблем с производительностью. Создаем себе проблему и решаем ее костылем (непродуманная-архитектура#1). Сами глянте, какое количество людей, которые борются с производительностью ангуляра. Да если вы в гугле вобьете angular performance, то вы ужаснетесь количеству статей, описывающих как его ускорить, не является ли это достаточным аргументом, в пользу того, что ангуляр медленный?

    Тут есть еще один момент, иногда все-таки двух сторонний дата-биндинг нужен, но UI все равно тормозит. Например при первой загрузке пользователь видит {{ выражения в скобочках }}. Хм… так это ж не баг, это фича! Нужно ввести директиву, которая будет прятать UI, что бы пользователь не видел мерцания, и не мешал фреймворку решать его несуществующие проблемы. И для этого вводится директивы ngCloak, ng-bind, ng-bind-template, которые собственно этим и занимается. Этих проблем бы не было, если бы использовался более шустрый фреймворк, который сразу показывает данные, как только они появились, ангуляр же после появления данных, требует времени что бы их отобразить. Опять создаем себе проблемы и решаем костылями (непродуманная-архитектура#2).

    И если у фреймворка появляются такие проблемы с масштабируемостью, не значит ли это, что что-то на фундаментальном уровне не так? Лаконичные и продуманные технологии, как правило масштабируются очень хорошо.

    Dependency Injection


    Следующий пример того, как ангуляр сначала ставит грабли, а потом заставляет вас плясать с бубном, что бы их обойти — это Dependency Injection. В ангуляре переменные внедряются по имени аргумента:

    function MyController($scope, $window) {
        // ...
    }
    

    Здесь ангуляр вызывает у функции .toString(), берет названия аргументов и потом ищет их в списке со всеми существующими зависимостями. Поиск переменной по имени — это еще терпимо, учитывая типизацию JavaScript, а проблема тут в том что, ЭТО ПЕРЕСТАЕТ РАБОТАТЬ ПРИ МИНИФИКАЦИИ КОДА. Когда вы минифицируете свой код, то он перестает работать, потому что переменные инжектятся по имени. Вам либо нужно использовать такой синтаксис:

    someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {
    }]);
    

    Или такой:

    MyController.$inject = ['$scope', '$window'];
    

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

    Следующая важная часть — это то, как зависимости объявляются. Прежде чем внедрять зависимость ее нужно как-то объявить. Как это можно было сделать, если вы психически здоровый человек:

     injector.register(name, factoryFn); 

    Где name — это название зависимости, и factoryFn — функция, которая будет инициализировать зависимость. Вот и все. Буквально в одном предложении уместили очень лаконичную идею. Теперь смотрим на то что предлагает ангуляр docs.angularjs.org/guide/providers. Там вводятся 5 новых сущностей: provider, service, factory, value, constant (непродуманная-архитектура#4). И каждая из них чем-то отличается друг от друга, но по сути это все одно и то же. Но самое главное, что все они могут быть легко заменены одним методом, который я привел выше. Но это слишком просто и не интересно, уж лучше давайте заставим людей мучится.

    Дебаггинг


    Дебаггинг сам по себе сложный, но этого мало, нужно это усложнить! Ангуляр питается вашей болью и страданьями!

    ОШИБКИ В БИНДИНГАХ ВООБЩЕ НЕ ВЫЛЕТАЮТ, например в вот этом коде:

    <div ng-repeat="phone in user.phones">
        {{ phone }}
    </div>
    

    если user не определен, то никакой ошибки не будет (непродуманная-архитектура#5). Ангуляр молчит как партизан. Более того вы не можете поставить брейкпойнт внутри {{ такого идиотского выражения }}, потому что это не JavaScript. Теперь идем дальше, ошибки, которые произошли в JavaScript'е ловятся внутренним ангуляровским перехватчиком, и ВОСПРИНИМАЮТСЯ БРАУЗЕРОМ КАК ПОЙМАННЫЕ ОШИБКИ (все что произошло в ангуляре, остается в ангуляре). Из-за этого приходитья ставить в хроме флаг «Pause on caught exeptions» (что бы дебаггер останавливался на всех ошибках, а не только на непойманных (обычно интересуют именно непойманные ошибки, которые выкидываются в консоль)), поэтому приходится в дебаггере проходить по всем внутренним пойманным исключениям ангулярки пока она инициализируется (непродуманная-архитектура#6) и только потом вы попадаете именно в ваше исключение. И тут-то вы увидите вот такой стактрейс:



    Ошибка вылетает из digest цикла и это означает, ЧТО ОНА МОГЛА БЫТЬ ВЫЗВАНА ИЗМЕНЕНИЕМ ЛЮБОЙ ПЕРЕМЕННОЙ ВО ВСЕМ ПРИЛОЖЕНИИ. Вы хрен когда проследите в дебаггере откуда растут ноги у ошибок. (непродуманная-архитектура#7)

    Наследование скопов


    Это без сомнения самая распространенная ошибка с которой сталкивался абсолютно каждый разработчик на angular. Например, если вы напишите вот такой код:

    <div ng-init="phone = 02"> {{ phone }} </div>
    <div ng-if="true">
        <button ng-click="phone = 911">change phone</button>
    </div>
    

    То при нажатии на кнопку переменная phone меняется не будет, в то время как в этом коде:

    <div ng-init="phone = {value: 02}"> {{ phone.value }} </div>
    <div ng-if="true">
        <button ng-click="phone.value = 911">change phone</button>
    </div>
    

    Все работает корректно, и номер телефона меняется при нажатии на кнопку. Либо например вот этот код, который даже опытных разработчиков поставит может поставить в тупик jsfiddle.net/1op3L9yo. Даже введен новый синтаксис для объявления переменных в контроллере через this, который решает эту проблему. (непродуманная-архитектура#8).

    Очевидно, что это поведение абсолютно бесполезное и очень вредное:
    • Если вы опираетесь в своей логике на наследование скопов, то такую логику становиться крайне сложно тестировать (нужно инициализировать еще состояние родительского контроллера).
    • Логика становиться более запутанной и неявной (вы используете переменную, которая в текущем модуле не объявлена)
    • Унаследованные переменные чем-то похожи на глобальные переменные (из дочернего скопа вы имеете доступ к абсолютно любой переменной из любого родительского скопа). А все знают, что глобальные переменные — это зло.
    • Увеличивает входной порог и количество теории, которую нужно знать: вам нужно знать прототипное наследование, вам нужно знать как работает tranclude и как можно поменять скоп в котором он работает, вам нужно знать что ng-repeat, ng-if, ng-switch работают со скопами по другому, вам нужно знать, что в директиве есть 3 разных параметра что бы указать какой скоп она создает внутри себя, да перечислять можно еще долго.

    Да по количеству вопросов на stackoverflow.com и статей в интернете можно уже понять, насколько это запутанная тема, вот такие вот дела, а кстати, что вы делаете сегодня вечером, я вот хочу какой-нибудь фильм глянуть, может посоветуете что-нибудь ? Даже в продвинутых стайл-гайдах советуют избегать использования $scope. И за 2 года работы на ангулярке я не встретил ни одного места, где обращение к переменным объявленным в родительском скопе было бы хорошей идеей (за исключением конечно стандартных директив типа ng-repeat, на реализацию которых мне, как пользователю библиотеки, вообще пофиг). Самое интересно, что такое поведение можно было бы избежать УБРАВ ВОЗМОЖНОСТЬ НАСЛЕДОВАНИЯ СКОПОВ (Например в ExtJs создается обертка над классами для имитации OOП, уверен, что и в каких-нибудь других фреймворках есть похожее). Обычно фреймворки должны прятать недостатки платформы и предоставлять в своем API логичное и максимально прозрачное поведение, но ангуляр наоборот бросает этот недостаток JavaScript вам в лицо и заставляет с ним драться. Из-за этого косяка был потрачен не один человеко-месяц.

    Директивы


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

    var myModule = angular.module(...);
    
    myModule.directive('directiveName', function factory(injectables) {
        var directiveDefinitionObject = {
            priority: 0,
            template: '<div></div>', // or // function(tElement, tAttrs) { ... },
            // or
            // templateUrl: 'directive.html', // or // function(tElement, tAttrs) { ... },
            transclude: false,
            restrict: 'A',
            templateNamespace: 'html',
            scope: false,
            controller: function($scope, $element, $attrs, $transclude, otherInjectables) { ... },
            controllerAs: 'stringAlias',
            require: 'siblingDirectiveName', // or // ['^parentDirectiveName', '?optionalDirectiveName', '?^optionalParent'],
            compile: function compile(tElement, tAttrs, transclude) {
                return {
                    pre: function preLink(scope, iElement, iAttrs, controller) { ... },
                    post: function postLink(scope, iElement, iAttrs, controller) { ... }
                }
                // or
                // return function postLink( ... ) { ... }
            },
            // or
            // link: {
            //  pre: function preLink(scope, iElement, iAttrs, controller) { ... },
            //  post: function postLink(scope, iElement, iAttrs, controller) { ... }
            // }
            // or
            // link: function postLink( ... ) { ... }
        };
        return directiveDefinitionObject;
    });
    

    Что бы понять этот синтаксис и зачем это нужно, надо действительно заморочиться. Вместо того, чтобы описывать ЧТО нужно сделать, вы больше заморачиваетесь на том КАК это сделать. И что самое обидное — ЭТА СЛОЖНОСТЬ НЕ НЕСЕТ НИКАКОЙ ПОЛЬЗЫ. Нету логических причин разделять логику на 3 метода (compile, link, controller), все это можно легко реализовать в одном методе. Опять таки смотрим какое количество проблем это породило. И учтите еще что в какие-то функции scope передается, в какие-то нет, какие-то функции выполняются один раз, какие-то каждый раз при $digest цикле, у каждой директивы так же имеется приоритет выполнения. Да даже, чтобы интегрировать какой-то код в мир ангуляра, например какой-нибудь jQuery плагинчик, вам нужно обернуть его обязательно в директиву. Потому что это было бы слишком просто, если бы разработчики могли сразу использовать готовые решения! И еще непонятно почему controller в директиве и реальный контроллер имеют одно название, они используются в совершенно разных местах и для разных целей, у них должно быть разное имя! (непродуманная-архитектура#9).


    Проблемы с людьми


    Во первых из-за того, что фрейворк чрезмерно сложный, мало разработчиков его понимают на действительно хорошем уровне и найти таких людей сложно. Во вторых серверные разработчики вообще не будут понимать, что творится на front-end'е и не смогут читать код. А это очень большой недостаток, создается черный ящик, в котором может разобраться только один человек в команде, и если этот человек уйдет, то никто не сможет его заменить. Это было бы нормально, если бы разработка на front-end'е действительно бы требовала таких сложных инструментов (например разработка GUI на ExtJs намного сложнее, чем на Angular, но там эта сложность оправданна), но нет, она сложная потому что сложности создаются целенаправленно. Если вы используете ReactJs или jQuery, то любой серверный разработчик, да даже любой программист, сможет разобраться в коде.

    Невозможность серверной шаблонизации


    Если вы попытаетесь использовать серверную шаблонизацию, например что бы ускорить прорисовку страницы, либо что бы поисковики индексировали (либо и то и другое), то вас постигнет разочарование. Т.к. серверная шаблонизация добавляет логики в HTML и AngularJs тоже пишет логику в HTML, то не происходит четкого разделения ответственности и как результат очень запутанный спагетти-код. Ангуляр просто не предполагает того, что разработчики захотят ускорить загрузку страницы, либо захотят индексацию поисковиками, он не создан для этого. (непродуманная-архитектура#11). Да, вы можете обойти эту проблему, используя prerender.io (это сервис, который парсит ваш SAP и выдает вам HTML файлы, которые вы должны скармливать поисковикам). Но опять таки — это костыль, а не коренное решение проблемы.

    AngularJs 2.0


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

    Важные вещи россыпью


    • Ужасная документация. Приходится дополнительно гуглить много информации.
    • До сих пор отсутствуют директивы для Drag and Drop событий (на момент написания этой статьи). Само по себе это не очень большая проблема, но это сигнализирует о продуманности продукта и внимании к деталям. Эти события уже поддерживаются подавляющим большинством десктопных браузеров и являются таким же базовыми, как и onclick или mousemove.
    • Когда вы пишите на ангуляре вы помещаете логику в ваш HTML. ng-repeat, ng-show, ng-class, ng-model, ng-init, ng-click, ng-switch, ng-if — что это как не помещение логики в представление. Само наличие такой логики — это не настолько страшно, как то что — это невозможно тестировать юнит-тестами (а это самые очень важные части приложения), невозможно продебажить и оттуда не кидаются ошибки (непродуманная-архитектура#12).
    • Гугл не использует AngularJs для своих основных продуктов (gmail, google+). И это вызывает подозрения, если это такой хороший фрейворк и они сами его создали, что тогда сами и не используют? Хотя например изобретенный в фейсбуке ReactJs они используют в facebook.com и в инстаграмме. Я знаю, что гугловцы используют этот ангуляр для других более мелких проектов, но все таки они не используют его в самых главных.


    Заключение


    Большинство проблем, которые я описал, можно обойти при желании (и мне приходилось их обходить, не бросать же проект, который сам написал). Но это тупиковый путь, это тоже самое, что ездить на ладе калине, вместо качественно сделанной иномарки. — Холодно в салоне? — Одевайтесь теплее! — Легко отваливаются детали? — А нечего их трогать, зачем они вам! — Шумит на большой скорости в салоне? — А вы включите магнитолу погромче, и ничего не слышно! И вообще если она сломалась — то просто приезжаете в салон и вам ее чинят. Вот ангуляр — это та же лада калина. Ездить можно, но вы гарантировано задолбаетесь. Факт того, что проблемы можно обойти НЕ ОЗНАЧАЕТ, ЧТО ПРОБЛЕМ НЕТ. Единственное хорошее, что ангуляр имеет — это то что он форсит разработчиков, разбивать код на модули, и код получается гранулированным, больше плюсов от использования ангуляра я не вижу. Вместо ангуляра лучше использовать React (предпочтительно) либо jQuery (для тех кто боится использовать реакт по какой-то причине), либо что-то еще, но уже на свой страх и риск потому что негативных отзывов о backbone, knockout и тому подобных тоже много. И я прошелся только по самым важным и заметным косякам, обычно когда программист говнокодит, он говнокодит везде, так что если вы собираетесь использовать этот фреймворк, приготовьтесь встретится не только с описанными проблемами, но и с кучей других, более мелких, но все равно проблем. Я не знаю почему ангуляр популярный, но это точно не потому что это хороший фреймворк. Поэтому я категорически не советую использовать текущую версию ангуляра. Надеюсь мой опыт поможет кому-нибудь принять правильное решение при выборе стека технологий для следующего проекта.

    Источники


    Why you should not use AngularJS
    What I would recommend instead of Angular.js?
    React vs AngularJS – How the two Compare
    From AngularJS to React: The Isomorphic Way
    The reason Angular JS will fail
    Pros and Cons of Facebook's React vs. Web Components (Polymer)
    AngularJS: The Bad Parts
    What’s wrong with Angular.js
    Things I Wish I Were Told About Angular.js

    P.S. Я хочу думать о бизнесс-логике и о том какие задачи мне нужно решить по факту, но я не хочу думать о бессмысленных суррогатных коцептах: наследовании скопов, когда нужно использовать односторонний или двусторонний дата-биндинг, когда нужно использовать compile, link, controller, когда мне нужно использовать value или constant, provider или factory, я не хочу думать о том, что делать когда я хочу интегировать натинвые события события в мир ангуляр, я не хочу думать должна ли директива видеть родительский скоп или нет, я не хочу думать о наследовании скопов в стандартных директивах и всех обходных путях, я не хочу думать о том, использовать мне глубокий $watch, обычный или $watchCollection, я не хочу думать о том, зачем нужны Provider для каждой внедряемой сущности и не хочу знать ничего о run и config фазах, я не хочу думать о том увидел ли пользователь {{ скобочки }}, я не хочу решать проблемы производительности, там где их нет, я знать не хочу о том, что такое трасклюд и как он работает со скопами. ГОСПОДИ, АНГУЛЯР ОТПУСТИ, ВЕДЬ Я НЕ В ЧЕМ НЕ ВИНОВАТ, ДАЙ МНЕ ПОЖАЛУЙСТА ПО ПРОГРАММИРОВАТЬ, МНЕ ЭТО НРАВИТСЯ.
    Метки:
    Поделиться публикацией
    Реклама помогает поддерживать и развивать наши сервисы

    Подробнее
    Реклама
    Комментарии 387
    • +2
      AngularJS с его замысловатым способо организовывать директивы (за него уже извинились) — это меньшее из зол на сегодня.

      В сложных приложениях, как раз при помощи DI главным образом, датабиндингами (не нравятся двусторонние — используетй one-time) количество проблем сокращается драматически по сравнению с классикой в виде jQuery. ReactJS упрощает биндинг не касаясь другого.

      Все якобы недостаки говорят только о том, что «вы просто не умеете его готовить» =)

      > ЭТО ПЕРЕСТАЕТ РАБОТАТЬ ПРИ МИНИФИКАЦИИ КОДА.
      npm install ng-annotate

      >УБРАВ ВОЗМОЖНОСТЬ НАСЛЕДОВАНИЯ СКОПОВ
      Не доконца ясно зачем, но хочется не наследовать — создайте изолированный scope.

      >ОШИБКИ В БИНДИНГАХ ВООБЩЕ НЕ ВЫЛЕТАЮТ
      Это позволяет в большинстве случаев игнорировать undefined и null — меньше кода — лучше читаемость.
      Если очень хочется и у вас почему-то сложные выражание — отлаживайте

      >Проблемы с людьми
      Нужен только человек с хорошим Javascript — остальное налаживается за пару недель интенсива.

      И далее по списку.
      • +41
        ng-annotate — это не решение проблемы, это чистой воды костыль. Вместо того, что бы сделать так, что бы все работало без плагинов (и это легко выполнимо), придумывается плагин, который исправляет косяки.

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

        Зачем я должен использовать другой дебаггер, когда стандартный в разы более функциональный и удобный. Тот дебаггер не покрывает даже 20% функционала стандартного, да и создавались они с разной целью и это не замена.
        • –2
          Вместо того, что бы сделать так, что бы все работало без плагинов.

          function.$inject = ['$scope']? На практике ng-annotate справляется с этим наура самостоятельно. Меньше кода — лучше читаемость.

          Плюсов от прототипного наследования никаких не вижу.

          Зачем теоретизировать. Вы постройте нормальное приложение то со вложенными контроллерами, директивами и далее. И увидите.
          • +15
            Вопрос, возможно, глупый. Но что, если я не хочу использовать ноду? Вот хочу я сократить количество задействованных решений. Что тогда?
            • +15
              Немного дополню предыдущий вопрос. Когда мы говорим об использовании ноды для сборки и минимизирования яваскрипта в приложении (для production-версии), при условии, что работоспособность самого приложения на develop-, testing-, staging-, production- и остальных окружениях ни коем образом от ноды не зависит, это я еще могу понять. Когда речь об автотестах, например… ясно. Но если мы не используем ноду (пишем на python, например, или на, прости господи, php). Я не понимаю желания приплетать дополнительные решения в такую карусель.

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

              PS
              Господа, когда так остро реагируете — поясняйте, пожалуйста, свою реакцию, а то не интересно.
              • 0
                Хм, а что именно в ангуляре требует сервера на ноде? Всё работает и без неё. Примеров полно даже в официальной страничке примеров, если по ним погулять, можно найти много на руби или просто статике, есть даже на c#.
                • +9
                  Человек имеет ввиду: как сборка фронтенда относится непосредственно к реализации бэкенда. Ответ — никак. Просто в ноде больше всего инструментов для этого было разработано.
                • 0
                  Большая часть всяких шаблонизаторов, препроцессоров и систем сборки фронтенда была реализована на node.js и ruby. Так просто исторически сложилось. Я тоже хотел бы прикрутить сборку к своему Play2 или golang'у (python не годится для масштабируемых реактивных приложений с push-нотификациями, и без костылей типа celery или микросервисных архитектур, а «прости-Господи» РНР вообще ужасен), к сожалению сущесвтующие решения на ноде очень сильно обгоняют всё остальное по функционалу. Вот мой немного кривой gulp-seed для примера. В случае с ангуляром так ещё есть перепаковка всех шаблонов в один большой js файлик который сразу ложится в кэш браузера при загрузке приложения, и другие довольно полезные вещи. А ещё я люблю писать шаблоны под Angular на jade, а вёрстку в Stylus, и получается целая вязка бубликов. В принципе фронтэнд, есть фронтенд — он просто кушает RESTful API и на сервере ничего не рендерится, и абсолютно всеравно на чём этот сервер будет написан — сборка фронта нам просто отдаст кучу больших файликов с ещё большей кучи мелких, и спрайты упакует, и векторные иконочные шрифты соберёт, и вектор под каждую плотность экрана растерезирует. Для того что бы не было проблем с SEO — просто прикручивают prerender.io, но я не поощряю такого подхода. Гораздо проще гонять тот же react прямо в node.js без каких либо заморочек с webkit'ом. Также gulp асинхронен без лишних побочных эффектов если его правильно готовить, и в нём есть возможность LiveReload'a.
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • +3
                      Ну вот далеко не всегда
                      • +1
                        То есть, YUI тоже не вариант? Хоть какое-то сжатие. Плюс gzip.
                        • +2
                          Gulp с Livereload'ом и асинхронным building pipeline'ом намного веселее. И в него тоже можно интегрировать YUI.
                • +2
                  А как вы предлагаете сделать так, чтобы все работало без «плагинов»?
                  Если не хочется наследования — существует «controller as» синтаксис. А плюсом является доступ из контроллера к scope парентовых контроллеров без директив и всяческих $parent
              • –7
                Извините, но ваша статья похожа на «заметки белок истеричек». Невозможно читать.

                что это как не помещение логики в представление

                Вы говорите как должны выглядеть данные, которые передали в слой view. Это логика отображения, а не бизнес логика, все на своих местах.
                • +2
                  Кстати, если она становится сложной, то её всегда можно поместить в функции.
                  • +8
                    Кстати да, так часто люди принимают за любой код в представлении — бизнес-логику, что страшно.

                    Позволю дополнить примером:

                    <div onclick="DB.query('update table1 set field1 = 1 where field2=2')"></div>


                    Вот это смешение бизнес-логики и представления.

                    <div onclick="this.style.top='1px;'"></div>


                    Это смешение императивного и декларативного кода, но все это касается только представления.
                    • +10
                      Приведу пример типичного шаблона для twig/jinja2 и такой же для angular.

                      {% for item in list %}
                      <div class="item {% if item.draft %} item--draft {%endif %}">
                          {{ item }}
                      </div>
                      {% endfor %}
                      


                      и

                      <div class="item"
                              ng-repeat="item in letter.list"
                              ng-class="{'item--draft': item.draft}"
                      >
                          {{ item }}
                      </div>
                      


                      Мне порой кажется просто что люди не понимают что это не HTML а XML-based синтаксис шаблонов и только. Там нет никакой ереси типа onclick и т.д. Так же согласен что люди частенько любую логику воспринимают именно как бизнес-логику.

                      Вообще порекомендую автору статьи подышать свежим воздухом и вглянуть на Angular2 где уже даже сейчас видно что была проделана неплохая работа над ошибками. Да даже если брать Angular1.3 и Angular 1.1 разница чувствуется.
                      • +18
                        Они очень много переделали в Angular2 как я посмотрю. Это означает, что даже разработчики фреймворка в какой-то степени понимают что были большие ошибки.
                      • НЛО прилетело и опубликовало эту надпись здесь
                        • +1
                          Нужно понимать, что React хранит и предполагает получение View-Model состояния с сторонних источников, с последующим вызовом обработчиков для перестройки VirtualDom дерева, и по другому это просто нереализуемо. Другие шаблонизаторы будут тупо оперерировать пустым HTML — создавать бешеный overhead на перерисовки и его разбор, и Angular тоже не исключение. Поэтому появляются такие странные вещи как ngReact :x Вьюхи не генерятся кусками — они формируют дерево компонент со своими состояниями, это может быть и непривычно и я сам не поощряю такой дизайн, но сделано чисто для реюзабельности и простоты работы с DOM деревом.
                          • НЛО прилетело и опубликовало эту надпись здесь
                            • +1
                              Адепты гуглополимеров с вами не согласны.
                              Не дизайнер, а верстальщик… дизайнерам вообще не положено лезть в вёрстку.
                              Верстальщику не составит особо проблем разобраться с компонентами, да и кто сказал что он увидит слишком большую разницу между HTML и JS с React компонентами. Эт только заядлые ригидные фанатики будут материться, а для всех остальных — обучится чему-то новому счастье.
                              • 0
                                Причем тут дизайнер и HTML? Пусть фронтендом занимается фронтенд-разработчик, который умеет все, что нужно.

                                Вообще react все правильно делает, используя pure js. Они не создают лишних сущностей в виде yet another template language, в отличие от всех остальных. Свой язык шаблонов — это дичайший оверхед на всех уровнях, и, что самое смешное, в итоге он скомпилируется в тот самый JS.
                                И к тому же, вот вы задумайтесь, долго вы учили директивы angular-а, отдельный кривой и убогий язык? А тут уже всем знакомый JS, отвратительный, но знакомый, более того, прекрасно отлаживаемый на лету.
                                • +7
                                  Как ни странно — все как раз наоборот. Это по собственному опыту где-то на 150 KOC с помощью React+Backbone.

                                  React отвечает только за представление. Используется JSX (с препроцессором, понятно), который похож на HTML, но не совсем. Так как все бьется по компонентам, в большинстве случаев получается древовидная иерархия (а не граф), что хорошо влияет на структуру проекта. Ну а поскольку все в изолированных компонентах — их легко тестировать. Очень легко.

                                  Добавляем backbone (модели+роутинг), require для зависимостей, etc и получаем отличный фреймворк под свои задачи.

                                  У нас есть верстальщик, который максимум что может это подключить плагинчик jQuery. Т.е. не программист вообще. Но вот HTML пишет хорошо. И его получилось очень быстро обучить следующему алгоритму:

                                  1. Делает обычную HTML верстку для страницы включая CSS
                                  2. Он связывается с фронтендщиком, они обговаривают логическую иерархию компонент (как бить кусок HTML на части)
                                  3. Разбивает свою же верстку на компоненты в соответствии с иерархией и отдает фронтендщику без логики
                                  4. Фронтендщик добавлет логику

                                  Так вот, я хочу сказать что конвеер отлично работает. Код остается читабельный — находить ошибки очень легко, учитывая доступный плагин для Chrome Dev Tools. Из за иерархии компонент можно легко найти что за что отвечает. Без каши из scope, без отдельного DSL для шаблонов (JSX не считается — он только теги оборачивает, все остальное в JS). И самое главное — приложение все же пишет программист, который понимает что такое производительность, качество кода и тестируемость.

                                  Думаю следующий вопрос — а как это все поддерживать? Да очень просто. Если изменения небольшие (CSS класс добавить, например) — это может сделать и верстальщик. Если что-то больше, то смотри пункты выше.

                                  И что я хочу добавить, после 50 KLOC проекта на AngularJS — React это просто чудо.
                                  • +2
                                    Расскажите про опыт: как оно React + backbone. Как правильно разделять их, что бы потом не плакать?

                                    Какие есть практики для динамического апдейта данных с сервера?

                                    Вот мне приезжают данные из вебсокета: мне правильнее на уровне бекбона вмерживать апдейты в имеющуюся структуру или просто пересоздавать всё и отдавать потом результат на рендеринг в реакт?

                                    Если вопросы некорректные, то буду рад, если поправите.
                                    • 0
                                      Посмотрите эту презентацию staltz.com/dont-react/#/
                                      • +3
                                        Там автор начал за здравие (о различиях интерактивного и реактивного программирования), а кончил как обычно (написал интерактивный велосипед, обозвав его внезапно реактивным)
                                      • +4
                                        Backbone и React живут параллельно. От Backbone мы используем Collection, Model и Router.

                                        Архитектура приложения типовая three-tier: сверху у нас UI, по середине слой Business Logic, снизу Data Access). Компоненты React просят что-то у BL, тот считает или просит у DA.

                                        Да, у нас тоже есть realtime update — сервер может что-то пушнуть. Сделано через обычный shared state (который спрятан в BL). Компонента React подписывается и когда что-то приходит — ее уведомляют. Построено поверх событий Backbone. В нашем конкретном случае модели для обновлений не используются — сообщения обрабатываются в BL и передаются отдельными объектами.

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

                                        Для всяких AJAX запросов — обычные коллекции и модели Backbone. Для React написан небольшой mixin, который умеет слушать .change() события для моделей (и автоматически отписываться если уходит из Virtual DOM) за счет чего получается реактивность.

                                        Ну и насчет вопроса про пересоздавать. Если кратко — React вообще все равно что за данные и откуда они приходят. Если более развернуто: React ожидает что метод render() вернет дерево компонент. Каждый раз — целое дерево компонент. В идеале, render() это чистая функция от аргументов компоненты и внутреннего состояния компоненты.

                                        В связи с этим, если надо отрисовать массив из 10 элементов, внутри которого меняется только 1 элемент, render() каждый раз будет возвращать все 10. И React уже сравнивает что именно поменялось, по сравнению с предидущей версией DOM и обновляет только то что нужно. А, поскольку, виртуальный DOM это просто структуры данных JS, то работает это все достаточно быстро. Это совершенно не отличается от подхода в том-же AngularJS, разве что более явно (с соответствующими плюсами, так как можно оптимизировать).
                                        • +2
                                          Слушайте, а если есть о чем написать, может, сможете поделиться опытом в виде поста на Хабр? Очень интересны нюансы реализации.
                              • 0
                                Дополнил немного статью: это невозможно тестировать юнит-тестами, невозможно продебажить, оттуда не кидаются ошибки и при добавлении большего количества логики в onclick он значительно усложнится для чтения.

                                По поводу ошибки в термине — суть не в том, какой термин используется, а в том, что под ним подразумевается.
                                • НЛО прилетело и опубликовало эту надпись здесь
                                  • НЛО прилетело и опубликовало эту надпись здесь
                                    • +17
                                      Ты просто слишком не конструктивно настроен. Я пишу эмоционально, но подкрепляю фактами, ты выдираешь что-либо из контекста, и агрессивно просишь меня, что-то тебе доказать. Если бы ты был более конструктивен и привел весомые доводы, я бы тебе ответил.
                                      • НЛО прилетело и опубликовало эту надпись здесь
                                        • +41
                                          Вместо того чтобы друг-друга обкидывать «нубасами», грамарнаци и неконструтивом — давайте аргументы, почему тестируется/не тестируется — вас тут слушают внимательно, вы не в привате общаетесь :)
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                          • +1
                                            А пока что в каждом Вашем жирном капсе читается фанатичная истерика

                                            Ага
                                          • +1
                                            Фактов по поводу unit-тестов Вы не привели. Необходимость дебага выражений в шаблонах больше говорит о программисте, чем об AngularJS.
                                          • +6
                                            Судя по статье, он совсем не полный ноль.

                                            У нас ангуляр используется в нескольких проектах последние полтора года и в целом мы им недовольны. Сейчас новый проект переводится на Backbone и разница просто чумовая. На простейшем коде ангуляровский проект подтупливает и подлагивает.

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

                                            С backbone страничка меняется до того, как отпускаешь мышку.

                                            Нет, спасибо, что-то дальше ангуляр с его скрытыми глобальными переменными в виде наследованных скоупов не очень хочется.
                                              • +2
                                                Да-да, я подобные аргументы видел до перехода с jQuery на ангуляр.

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


                                                Ну вы бы что ли ссылку дали или use-case подробнее описали. Если бы такое имело место сколько-нибудь широко, Angular бы вообще никто не использовал.
                                                • 0
                                                  Дать ссылку я вам на админку у пользователей я по понятным причинам не могу, могу дать триальный ключ к нашему стриминговому серверу и могу пояснить, как добавить 800 тестовых потоков, что бы вы увидели, как оно перестает работать на таком небольшом количестве строк.
                                                  • 0
                                                    Да вобщем-то хватит и описания: правильно я понял, что Вы одновременно отрисовываете 800 progress bar-ов с какой-то информацией для каждого элемента?
                                                    • 0
                                                      не, не прогресс бары. 800 строк в таблице, в каждой информация о потоке: время жизни, количество клиентов, битрейт и т.п.

                                                      Некоторые строчки можно развернуть, что бы увидеть подробнее информацию о конфиге, клиентах и т.п.
                                                      • +2
                                                        Ясно. Сложно, правда, представить 800 элементов на полупустой странице.

                                                        В общем это как раз те случаи «100500 элементов на одной странице». Везет мне как-то на клиентов — они такое плохим UX считают. Но проблема не является непреодолимой. Причём вариантов решения больше одного. Хотя если у Вас большинство страниц такие, то AngularJS вам, похоже, ни к чему. Выбор инструмента под задачу, все же, никто не отменял.
                                                        • 0
                                                          такая страница ровно одна. Разбить эти строки как-то по-другому (постранично) не очень то получается.
                                                          • 0
                                                            В концепцию реакта отлично ложится:

                                                            1. Компонент для потока. Рисует информацию об одном потоке.
                                                            2. Нужен какой-то простой маршрутизатор сообщений. Компоненты потоков подписываются на события из этого роутера и получают «свои» обновления
                                                            3. Вебсокет клиент кидает входящие данные в роутер
                                                            4. Компоненты получают новые данные, обновляют свое состояние
                                                            5. Обновление состояния автоматически запускает render() для компоненты
                                                            6.…
                                                            7. Профит
                                                • 0
                                                  То же самое — пришлось переписать приложение с AngularJS на Backbone+MarionetteJS. В форме с 50-100 полей получились более 7000-10000 watcher'ов, после попыток оптимизации число сократилось до 3000. При этом реакция на нажатия клавиш запаздывала на 0.5-1 секунду. Переписал на BB — всё летает, никаких тормозов. Конечно больше ручной работы, надо следить за утечками памяти.
                                                  • 0
                                                    Какие антипаттерны приводят к утечкам?
                                                    • 0
                                                      Да там не антипаттерны, просто в Backbone нужно закрывать свои view.
                                                    • 0
                                                      А для биндингов данных в полях форм вы что использовали? Расскажите пожалуйста!
                                                      Я попробовал Stickit, но он оказался не очень гибким. Перешел на Rivets.
                                                      • 0
                                                        Использовал stickit там, где он мог, сложные вещи руками. Rivets вроде смотрел, но не помню почему отказался от него.
                                          • +58
                                            Извините, но ваша статья похожа на «заметки белок истеричек».

                                            Нет, не похожа. Автор выразил свое мнение. С тезисами, с аргументами, с доказательствами.
                                            Со всем тем, чего нет у вас в комментарии.
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                              • +17
                                                Лучше раскажите почему вы считаете, что он неправ. И как бы вы решили эти проблемы.
                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                  • +27
                                                    Тратить своё время, чтобы рассказать ему обо всех его ошибках в Angular?

                                                    Ну вы же тратите свое время, сидя на хабре и постя неаргументированные комментарии. Комментарии (в частности) для того и нужны, чтобы указывать автору поста на его ошибки, разве нет?
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                      • 0
                                                        Уже перелопатил и отписал ниже.
                                                    • +1
                                                      я давно ищу человека, который помог бы нам с неработающим куском кода на ангуляре, но вам я бы не хотел платить деньги.
                                                    • +34
                                                      1. Data-binding и его возможные тормоза. Простой ответ — за удобство приходится платить. Нефиг всю логику на него завязывать. Понятно, что watchCollection на тысячи элементов будет тормозить. Поэтому никого не должно удивлять, что особо критические места, возможно, придется оптимизировать ручками и без байндинга (гриды/чарты/etc). Вообще напоминает недавний пост про сборщик мусора в C#, который якобы течет и тормозит — а у автора просто-напросто объекты во второе поколение и LOH попадали очень быстро
                                                      2. DI. В JS невозможно его реализовать с использованием типов аргументов, как в нормальных языках, поэтому приходится использовать алиасы. Есть три возможных варианта использования, один из которых не дружит с минификацией или, например, с неймспейсами. Проблем с двумя другими нет. Автору только считает синтаксис уродливым. Срочно всем перестать использовать ангуляр! По поводу 5 «новых» сущностей и мучающихся людей. Тут просто сказать нечего, у некоторых этих сущностей вообще-то даже разный жизненный цикл
                                                      3. Дебагинг. Не самое приятное дело, да. Но дебагинг в среде, построенной на асинхронных событиях от браузера, вообще штука печальная
                                                      4. Наследование scope'ов. Нужно. Все в сервисы не понапихаешь, хотя бы потому, что они синглтоны. И да, 'Controller As' синтаксис. Хотфикс примера на fiddle — jsfiddle.net/1op3L9yo/253/. Вообще пример хороший, заберу в качестве задачки на собеседования с вопросом «почему так?» :)
                                                      5. Синтаксис директивы довольно сложный, да. Но как правило сокращается до scope, restrict и link. Остальное иногда пригождается. Пункт аналогичен — не пишите на Java, там стопиццот различных ключей в командной строке.
                                                      6. Проблемы с людьми — так на любой технологии эти проблемы, сильные разработчики работу долго не ищут :) Адекватные разработчики основы понимают довольно быстро, а структурированность ангуляра сильно помогает, особенно тем кто имеет опыт в бэкенде. Если лабать визитки на JQuery последние лет 5, то да, есть опасность разрыва шаблона. Но черт возьми, это же не C++!
                                                      7. Серверная шаблонизация — наверное единственный стоящий пункт здесь. Никто не мешает генерить HTML template на сервере тем же .NET'ом или каким-нибудь шаблонизатором, но мне кажется имелось в виду нечто типа isomorphic js раз уже SEO помянут. Мы эту проблему не решаем, у нас немного иной класс приложений :)
                                                      8. Документации достаточно. Если есть проблемы с тем, как и почему использовать — это не в документацию, а на амазон за литературой
                                                      Остальное по 10 раз объяснено в других комментариях.

                                                      Собственно народ и накинулся, потому что единственная реальная проблема (шаблонизация?) в статье затронута так, что приходится гадать, а что собственно имелось в виду? Все остальное из разряда — тут синтаксис плох, там слишком сложно, это ниасилил.
                                                      • 0
                                                        Но дебагинг в среде, построенной на асинхронных событиях от браузера, вообще штука печальная

                                                        Отходя от темы на 100%. Почему печальная?
                                                        Если не использовать паттерн «коллбэк в коллбэке, коллбэк погоняет» то даже как-то очень просто.
                                                        Или вы про что-то конкретное?
                                                        • +1
                                                          ну человек жалуется на то что у него стэк-трейс режется до digest-loop'а. Но он всегда будет резаться, потому что колбеки всегда будут, даже при использовании promise'ов, которые их по сути всего лишь прячут. На ответ от сервера, на банальный setTimeout чтобы отдать управление браузеру, и т.д. Пример, где «не печально» — async/await шарповые
                                                          • 0
                                                            К слову по поводу этого, есть чудная библиотечка под названием zone.js, одной из возможностью которых является построение нормальных стактрейсов.

                                                            p.s. Эта библиотечка будет использоваться в Angular2 для запуска $digest циклов (если браузер не поддерживает Object.observer то используется старый добрый дирти-чекинг)
                                                            • 0
                                                              Точку зрения понял. Что до шарпа, то нет нормального опыта и понимания, поэтому ничего не скажу.
                                                  • +2
                                                    Таки автор аргументировал свою точку зрения.
                                                  • +2
                                                    >Двусторонний дата-биндинг

                                                    Есть bindonce https://github.com/Pasvaz/bindonce
                                                    В 1.3 можно прямо так {{::item}}
                                                    • +8
                                                      До сих пор отсутствуют директивы для Drag and Drop событий

                                                      github.com/angular-dragdrop/angular-dragdrop
                                                      github.com/fatlinesofcode/ngDraggable

                                                      Или вы хотите сказать что такие вещи должны быть вшиты в фреймворк и быть доступны из коробки?

                                                      Когда вы пишите на ангуляре вы помещаете логику в ваш HTML

                                                      Логику представления, заметьте, где ей самое место. Если там что-то сложное то это проблема разработчика а не фреймворка. И коль уж вздумалось вам тестить UI так и пишите UI тесты (e2e тесты если быть точнее). Ну или сложную логику можно опять же инкапсулировать в директиву и покрывать быстрыми юнит тестами уже оные штуки.

                                                      Гугл не использует AngularJs для своих основных продуктов

                                                      Гугл много чего не использует из того, что было сделано его сотрудниками в свободное от работы время. И таки гугл использует на паре мелких в масштабе гугла проектов (youtube 4 psp, DoubleClick Digital Marketing)

                                                      Гугл может передумать и закрыть этот проект.

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

                                                      • 0
                                                        Вместо ангуляра лучше использовать React
                                                        В тегах не увидел ничего о Node.js


                                                        Так что хочу задать вопрос еще и автору статьи. Можете ли вы поделиться туториалом такого приложения с бэкендом, не зависящим от Node.js? Такое ощущение, что для разработчиков одностраничных приложений весь остальной мир исчез и состоит только из Node.js (против которой я ничего плохого сказать не могу, кстати!).
                                                        • +20
                                                          Например при первой загрузке пользователь видит {{ выражения в скобочках }}

                                                          У меня создалось впечатление что автор лукавит по поводу своего опыта работы с AngularJs. Если бы вы прошли хотя бы официальный tutorial, вы бы знали как это решается. Или же вы намеренно не упомянули о директиве ng-bind и ng-bind-template, что указывает на ваше предвзятое отношение к фреймворку, и на то что вы искали к чему бы докапаться.

                                                          Конечно существует множество спорных моментов и недоработок, но технология новая и активно развивается. Писать большими буквами «НЕ ИСПОЛЬЗУЙТЕ АНГУЛЯР» выгладит глупо и по-детски. Мне эта технология помогла решить много проблем в сложных приложениях и она мне действительно очень нравится, но я не стану кричать всем «ИСПОЛЬЗУЙТЕ AngularJs, {{ваш_фреймворк}} отстой».
                                                          • +12
                                                            Если бы вы прошли хотя бы официальный tutorial, вы бы знали как это решается.
                                                            Автор пишет что решение есть, но есть один большой нюанс… Могли бы обойтись и без решения. Т.е. мы сначала создаём проблему, потом создаем её решение, и так много где в ангуляре => что-то не так в архитектуре даже если это помогает что-то решить. Собственно весь пост к этому и сводится, пусть немного истерично, но всё же. И, судя по второй версии ангуляра, разработчики angularjs об этом знают и идут верным путем, но не торопясь(по причинам описанным вами же)
                                                            • +4
                                                              Автор пишет что решение есть

                                                              Покажите мне где автор пишет о решении? Если вы имеете ввиду директиву ng-cloak, которую он упомянул, то это не решение, а затычка. Костыль, если хотите, как автор его и назвал. И если вы его используете, то с большой уверенностью могу сказать что вы уже пошли не по той дорожке. Bad practice, как говорится. Это, как я уже говорил, показывает что у автора просто недостаточный опыт.
                                                              В любом фреймворке вы найдете инструменты, которые использовать не желательно, и использование которых сигнализирует о том что вы неправильно его (фреймворк) используете.
                                                          • +8
                                                            Вполне обоснованно, а значит уместно. Для расширения кругозора и во избежании «зашеренности». Идеальных инструментов нет и все мы должны это понимать и принимать. И делать выбор в соответствии с задачей. Спасибо!
                                                            • +12
                                                              Это вы еще не пытались быть умнее фреймворка при работе с knockout.js
                                                              • +2
                                                                А поделитесь пожалуйста, с какими проблемами вы столкнулись при работе с knockout.js и как их решали?
                                                                • +3
                                                                  Все беды, в общем-то, из-за желания заниматься велосипедизмом.

                                                                  1. Начнем с того, что все KnockoutObservable<T>.subscribe(t => any) и KnockoutComputed имеют dispose(). Таким образом, если создавать SPA с кучей представлений, то рано или поздно память начнет течь. Поэтому приходится делать отдельно функцию, вызывающую .dispose() для всех локальных подписок и вычисляемых значений. Код начинает походить на C# или C++, где на каждый конструктор пишешь деструктор.

                                                                  2. В knockout поддержка асинхронной загрузки шаблонов появилась только в версии 3.3 и, насколько мне известно, только для knockout components. Естественно, что в большом приложении грузить все .html разом файлы смысла нет. Пришлось писать свой враппер поверх template, который учитывал бы все возможные варианты(шаблон уже есть в разметке, шаблон загружается, шаблон следует загрузить, работу с with, as, data, foreach)

                                                                  3. Любой более-менее сложный контрол требует простыни описания для конкретного случая. Писать в разметке по 5-10 строчек в data-bind было неинтересно, тем более, что typescript там не поддерживается, да и intellisense работает, мягко говоря, через раз. Я решил решить эту проблему возможностью вынесения кода из data-bind в отдельный файл с общим ключом привязки по строке. То есть <div data-bind=«bindId: 'myKey'» ></div>. Проблема начинается, когда через этот bindId проходит привязка, контролирующая дочерние элементы DOM. По логике, казалось бы, ты привязал данные, инициализатор привязки вернул { controlsDescendantBindings: true }, но это осталось в коде. Как только код добавляет (да через тот же foreach) элемент в документ, заболтивый нокаут бежит по всем data-bind указанным в разметке, и не найдя там привязки, вернувшей controlsDescendantBindings, начинает повторную привязку. Самое ужасное, что во время первой инициализации все нормально и глюк может иногда не воспроизводиться. Таким образом для слишком умных привязок или приходилось добавлять привязку-пустышку data-bind=«stopBinding: true», все тело которой controlsDescendantBindings: true, или отдельно учитывать эти моменты в инициализаторе bindId.

                                                                  Кстати с новыми pureComputed я тоже не очень хорошо подружился, так что катить бочку раньше времени на них не стану
                                                                  • 0
                                                                    С вашими аргументами я соглашусь, по этой и описанным уже тут причинам я стараюсь делать ui как можно проще, да и пользователям намного лучше, когда не приходится совершать кучи лишних действий. А вообще я использую фабрику виджетов — jquery ui widget (виджеты пишу свои или юзаю плагины для jquery) вместе с нокаутом и пока эта связка меня не разочаровала, может быть и вам стоит обратить на это внимание. Если проект нормально разбит по папкам, то проблем нет. И конечно же, нужно управлять загрузкой этих виджетов, но это уже другая история.

                                                                    Инструменты не совершенны, да.
                                                                    • +1
                                                                      А расскажите, как вы решаете следующую проблему: в разметке есть один div для popup. Биндинг к данным сделан в Knockout. Хочется через knockout открывать и закрывать (уничтожать) несколько попапов с разными данными. Есть ли красивое решение для этого?
                                                                      Что я делаю сейчас — делаю div невидимым, пишу обертку, которая при открытии попапа клонирует html и делает клону ko.applyBindings(). Имхо, это дичайший костыль.

                                                                      tl;dr Как в Knockout жить с моделями, которые могут быть дуплицированы и привязаны к разным данным?
                                                                      • 0
                                                                        Первой проблемы у меня не появляется, потому что я использую jquery виджеты и там логика у меня немного другая, можно попап написать свой и вешать его на любой элемент. Конечно, div попапа будет создаваться на каждый попап, но зато сразу решается ваша проблема. Вообще с этой фабрикой виджетов и нокаутом получается как в веб-компонентах — есть шаблон html файл отдельно, есть js код отдельно (виджет и есть модель), подгружаем два этих файла и всё хорошо (можно сделать простой загрузчик виджетов на 150 строк).

                                                                        Вторая проблема с моделями. Последнее время я использую централизованное хранилище (можно сделать очень простое, а можно покруче). Так получилось, что нам в компании для упрощения работы понадобилась реализация схем данных mongoose (node.js) на клиенте и пришлось реализовать этот механизм — в результате получился хороший storage со схемами данных, с валидацией, работающий с knockout + es5 (https://github.com/SteveSanderson/knockout-es5) + еще несколько других фишек из mongoose. Так вот, если использовать его, то получается, что все данные у вас в одном месте и вы просто запрашиваете их для конкретного виджета (в нашем случае). Пока, при таком подходе, я проблем не заметил.

                                                                        Если вам интересно, я могу сделать демку, поделиться своими наработками в плане нокаута.
                                                                        • 0
                                                                          Полагаю вам необходимо написать собственную привязку (binding) или компонент, который будет инициализровать разметку или еще чего, когда вам надо.
                                                                          Как я уже выше подмечал, можно указать, что bindingHandler будет сам обрабатывать дочерние привязки или вообще вручную работать с DOM.
                                                                • +14
                                                                  Ну есть проблемы да, ну а где их нет? Половина статьи описывает проблемы в духе нужно хорошо изучить фрэймворк, чтобы его использовать на полную катушку.

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

                                                                  >либо jQuery
                                                                  Лол, что? Надо было сразу прочесть конец и не читать статью.
                                                                  • +3
                                                                    2K датабайндингов лечится, об этом отписал ниже.
                                                                    • 0
                                                                      Да, читал про лечение, но хочется попробовать реакт. Он судя по тестам работает намного быстрее.
                                                                      • +1
                                                                        Реакт с ангуляром нельзя сравнивать, реакт это просто вид и загрузка дынных без контроллеров или сервисов.
                                                                        В ангуляр React спокойно интегрируется через ngReact.
                                                                        • 0
                                                                          Собственно по этому Ganesh и говорил про «возможно в связке с angular».
                                                                  • +2
                                                                    > Гугл не использует AngularJs для своих основных продуктов (gmail, google+). И это вызывает подозрения, если это такой хороший фрейворк и они сами его создали, что тогда сами и не используют?

                                                                    Nowadays, the framework is used by more than 100 projects just at Google, and it is maintained by its own internal team, in which Miško takes part.
                                                                    • +6
                                                                      У гугла просто море проектов (видимо из-за того самого «правила о скольки-то там процентах рабочего времени на свой прожект» чуть ли не у каждого сотрудника))) Естественно, большинство из них никому не нужны, а иногда они становятся огромными, но все равно умирают. Покажите в каких действительно _рабочих_ проектах гугл используется этот фреймворк? Похоже, что автор прав.
                                                                    • +38
                                                                      Автор немножко переборщил с эмоциями, но в целом первое впечатление от ангуляра передал верно.

                                                                      Я после просмотра туториала по дурости решил, что смогу склепать ui на ангуляре самостоятельно. В результате целую неделю собирал все возможные грабли и косяки (вот какого дьявола в диалоге автоматически создаётся лишний scope, например?) — а потом забил на это дело, и передал доводку UI фронтэндщикам. Дальше было чистейшее шаманство: ребята говорили, что «вот тут надо написать именно вот так, потому что только этот способ работающий, а тот, который я углядел в доке — он именно здесь не подходит, потому что такая магия», и это надо тупо выучить. Я серверный программист, я привык к тому, что всякие там фреймворки пляшут под мою дудку, а не заставляют учить заклинания.

                                                                      Ну, и если уж быть до конца честным, с годами ситуация с web-based ui как-то качественно лучше не становится. 6 лет назад я писал на ExtJS, и это было ужасно, потом мне здорово покушал нервов проект на JSF, теперь вот появился ангуляр — годы идут, а сложность, противность, и незрелость используемых инструментов никак не уменьшается. Печально это.
                                                                      • +27
                                                                        Лишь отчасти соглашусь с некоторыми суждениями, но СЛИШКОМ МНОГО BOLD'оВОГО КАПСА НИКОГДА НЕ БЫВАЕТ МНОГО.

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

                                                                        Ограничения $digest цикла можно легко преодолеть, об этом уже было написано тут и о результатах в 1200ms -> 35ms тут.

                                                                        DI не работает после минификации — в офф доках ангуляра прямо говорят (раздел Note on minification): используйте $inject, или аннотации. Опять же, не стоит ныть по поводу «мне влом написать 5-6 слов со знаком $ — этого не должно быть, это проблема фреймворка !». Указать минификатору наличие сторонних глобальных переменных не составляет особого труда, и это никак не относится к дизайну самого фреймворка.

                                                                        По поводу «нетестированности» самого фреймворка, а автор пробовал Protractor с ngMock'ом? Есть $exceptionHandler и им вполне так удобно перехватывать любые ошибки. Хватит ныть — читайте документацию.

                                                                        Наследование скоупов не имеет прямого отношения к ангуляру непосредтсвенного — это просто заморочка прототипного наследования в JS'e. Немного гугломагии подтверждает, и такого уже было написано очень много. Опять же, сами ангуляровцы в доках советуют не использовать глубокое вложение объектов внутри $scope потому что там будут глюки с $watch'ерами и $digest циклом. Использование нескольких уровней вложения в рамках одной директивы не поощряется, по тем же причинам что и указанны в статье… и это не является проблемой — ничего не мешает писать $scope.btnCaption вместо $scope.btn.caption.

                                                                        Синтаксис
                                                                        ng-controller="SomeController as OtherName"
                                                                        не более чем синтаксический сахар для избежания путаницы в описаниях контроллеров, и никакого отношения к проблеме не имеет.

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

                                                                        По сравнению с тем же backbone или ember — Angular совсем не сложный, и в нём ничего не протекает. Конечно после jQuery у людей странное выражение лица, но качественный богатый фронтенд не подразумевает место для поиска «плагина завоевания мира нажатием одной кнопки». Учитесь, и не нойте!

                                                                        Невозможность серверной шаблонизации… хм, ну это зависит как посмотреть на проблему — берём prerender.io, прикручиваем рендер страниц при изменении моделей, кэшируем нормально в Nginx'e и отдаём поисковым роботам. Не то что бы это было изящно, но и писать серверный рендер ангуляра под каждую платформу бессмысленно. Тем более такой подход при небольших нагрузках на запись вполне нормально работает. Для прозрачной клиент-серверной шаблонизации нужна трансляция OT-патчей в CQRS-ES'e — это довольно сложные подходы которые используются в корпоративных приложениях с незапамятных времён (привет vaadin, привет gwt, давно не виделись).

                                                                        А кто сказал что гугол не использует у себя Angular?

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

                                                                        Я не говорю что React плох, но сравнивать React с Angular'ом НЕЛЬЗЯ. React это лишь View и View-Model из MVVM, а Angular — чистое MVC. У ангуляра рендер реально слоупочный, и появляются такие странные вещи как ngReact (чую запах жареных мозгов). Я и сам спокойно гоняю React + rx.js в браузере, и на node.js, и вполне так доволен производительностью для средних проектов.

                                                                        Я надеюсь что во втором ангуляре исправят косяки рендера и начнут напрямую оперировать DOM деревом, без лишних перерисовок и перекомпоновок чего-попало.
                                                                        • +6
                                                                          Само собой, статьи на тему «почему не ангуляр» нужны. Но эта статья какая-то странная… Здесь скорее перечислены проблемы, возникающие при старте, чем какие-то фатальные недостатки, которые будут преследовать вас на протяжении всего процесса разработки.

                                                                          Собственно, из недавно прочитанного я бы посоветовал это:
                                                                          www.fse.guru/2-years-with-angular
                                                                          www.fse.guru/why-you-should-learn-angular-anyway
                                                                          • +8
                                                                            Я автор вышеприведенных статей.
                                                                            Статьи написаны «по верхам» с умыслом.
                                                                            Если у вас будут вопросы — то я с радостью отвечу :)
                                                                            • 0
                                                                              О, я тогда хочу вам сказать спасибо, за упоминание mithril.js в обзоре фронтенд-фреймворков. Чудесная штука.
                                                                              • 0
                                                                                Посмотрите еще cycle.js: github.com/staltz/cycle

                                                                                Правда, я бы не сказал, что это продакшн-реди фреймворки, подходящие под мои критерии. Но идеи и тенденции в них заложенны более здравые.
                                                                                • 0
                                                                                  Спасибо, я посмотрю на cycle и попробую разобраться с FRP еще раз. До сих пор не осилил как-то.
                                                                                • 0
                                                                                  Он сыроват пока, и для продакшена не готов (
                                                                                  • 0
                                                                                    Ну что ж поделать-то. Значит, нужно использовать в pet project-ах и ждать готовности. =)
                                                                            • +5
                                                                              «ага, тут кликнули по кнопке и изменилась модель, теперь нужно слушать изменения на этой модели и когда она меняется вызывается хэндлер», а не «кликнули на кнопку, вызвался хэндлер»

                                                                              Хм, ng-click=«clickHandler()»?
                                                                              ДВУСТОРОННИЙ БИНДИНГ — ЭТО НЕ ТО КАК ПРОИСХОДИТ ОБРАБОТКА СОБЫТИЙ В ПРИНЦИПЕ

                                                                              Угу, и, $watch() моевтон в 99% случаев, особенно в таких, которые вы описали.
                                                                              Еще двусторонний биндинг означает, что изменив что-либо в своем приложении, это тригерит сотни функций

                                                                              Странно, а я думал что там dirty checking цикл, и изменение переменной абсолютно ничего не триггерит.
                                                                              ТО ВЫ ТОЧНО УПРЕТЕСЬ В ЭТО ОГРАНИЧЕНИЕ

                                                                              Стоит подумать о своей архитектуре, а не об архитектуре ангуляра. Да, на RICH приложения он и не затачивался (это, кстати, к слову о gmail'e). Если вам нужно 1000+ биндингов, то вы неверно выбрали инструмент.
                                                                              Когда вы минифицируете свой код, то он перестает работать

                                                                              Когда это минификатор, особенно с агрессивной политикой оптимизаций, не требовал препроцессинга / своего стиля написания кода?
                                                                              Наследование скопов

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

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

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

                                                                              Программирование на достойном уровне вообще сложная штука. Даже без ангуляра более-менее сложное приложение не разобрать с наскоку. Ну скажем, если не хотите async hell'a, то у вас будут промизы, которые в серверных языках не всегда используются.

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

                                                                                Очевидно, но, надо признать, достаточно геморройно, особенно если юзаешь сторонние директивы и их приоритеты.
                                                                                • 0
                                                                                  Странно, а я думал что там dirty checking цикл, и изменение переменной абсолютно ничего не триггерит.


                                                                                  Обычно в сложном приложении получаются много $watch('xxx', function(...){...}). Вот они вызываются при каждом $digest цикле и не по одному разу.
                                                                                • +2
                                                                                  Недостатки будут везде, их не избежать.

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

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

                                                                                  P.S. Мой личный фаворит в недовольстве — «а давайте обернем весь остальной мир в директивы». Это просто ужас, делать столько бестолковой мало чем оправданной работы… При том что авторы того, что мы оборочаиваем тоже не дураки и часто их решения по подключению бибилиотеки просто в разы удобней всяких директив, за которыми надо еще следить потом.

                                                                                  • –7
                                                                                    Как всегда, собственно. Сначала всем всё нравится, но обязательно должен появиться кто-то, кто скажет, что это плохо. Думайте, наконец, своей головой, ей богу. Ни один из аргументов в статье нельзя воспринимать всерьёз.
                                                                                    • +3
                                                                                      Мне вот например не нравится бутстрап, который нравится очень многим :)
                                                                                      • +1
                                                                                        Не только вам.
                                                                                        Он гробит семантику разметки и задачи самого HTML5.
                                                                                        Так что годится не более чем для внутреннего использования и прототипирования.
                                                                                      • 0
                                                                                        Мне тоже. :) Но я хотел сказать не об этом. Автор статьи, толком не разобравшись с проблемами, вставшими у него на пути (а все эти проблемы вполне себе преодолимы), рекомендует нам не использовать Angular, что, по сути, весьма неразумно, учитывая все те прелести, что фреймворк нам предлагает.
                                                                                        • +6
                                                                                          Разве? По-моему автор часть решений проблем разобрал. Его позиция заключается в том, что это не практические проблемы, а проблемы плохого дизайна.
                                                                                    • +1
                                                                                      • 0
                                                                                        Вы мне только что как верстальщику камень с души сняли. А то я уже думал, что всё – дальше расти только в Angular/ReactJS/etc. Сейчас понял, что фигушки – лучше верстать буду хорошо, чем очень долго и очень плохо пытаться программировать сайты на инструментах для создания приложений.
                                                                                      • +3
                                                                                        После знакомства с Ангуляром мне в голову пришла следующая метафора.

                                                                                        Предположим, у нас есть некоторое приложение. Мы, как архитектор этого приложения, знаем как в нём организованы потоки данных. В приложении мы задекларировали эти потоки данных и то как их следует обрабатывать в виде некоторого кода. То есть у нас описаны некоторые конкретные блоки, которые связаны конкретными линиями-направлениями данных.
                                                                                        В противовес этому, Ангуляр представляет собой что-то вроде «множества универсум», где всё связано со всем. В первый момент это вызывает wow-эффект. В самом деле, путём нескольких деклараций и пары строк кода мы организовали полноценный ввод пользователя, обработку и автоматическое обновление представления (!). Но в дальнейшем становится ясно, что такая полносвязная схема имеет свои побочные негативные эффекты: низкая производительность и сложность восприятия.

                                                                                        Я был очень рад услышать, что идёт разработка Angular 2, который (как и обязано мажорному релизу) будет обладать существенными изменениями, и в частности упрощениями, выпиливанием целой кипы фич. Также, существует разработка angular-light, которая освещалась на Хабре и ознаменована той же цели: упростить и оздоровить Ангуляр.

                                                                                        После использования Ангуляра я пришёл к выводу, что лучше строить приложение, основываясь на явных потоках данных. Для этого лучше всего подходит идея FRP. Что замечательно, FRP прекрасно компонуется с существующими библиотеками (я считаю, компонуемость — это очень хороший признак действительно здоровой концепции), например, можно использовать jQuery для получения источников данных (пользовательские события, которые инициируют flow/поток), так и для отображения ($.text, $.html в конце цепочек), также FRP прекрасно дружит со всеми существующими шаблонизаторами.

                                                                                        В общем, явное лучше неявного, FRP и компонуемость это будущее.
                                                                                        • +2
                                                                                          Абсолютно согласен, на парадигмах FRP писали реактивный манифест.
                                                                                          Пробуйте React + rx.js если интересует полноценное FRP в браузере, и Typesafe Stack со Scala на сервере…

                                                                                          За реактивными приложениями действительно большое и светлое будущее.
                                                                                        • +1
                                                                                          На самом деле Angular никак вас в этом плане не ограничивает. Есть Angular-bacon для того что бы строить FRP в angular-based приложениях.

                                                                                          Более того, я лично вижу проблему во фразе «Angular-way». В частности, довольно популярная библиотека для работы с localStorage полностью построена на ватчерах и циклах дайгест. То есть просто так. Потому что это этот самый angular-way. Откуда у людей берутся такие идеи я не знаю.

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

                                                                                          p.s. основная идея Angular Light не в том, что бы «оздоровить» Angular, а в том что бы дать возможность использовать тот самый синтаксис шаблонов (а с ним и директивы + фильтры) без необходимости использовать полноценный фреймворк.
                                                                                          • 0
                                                                                            Такие идеи из примеров, пропагандировавших этот подход.
                                                                                            Ранняя документация имела конкретные намеки на angular way.
                                                                                            • +1
                                                                                              p.s. основная идея Angular Light не в том, что бы «оздоровить» Angular, а в том что бы дать возможность использовать тот самый синтаксис шаблонов (а с ним и директивы + фильтры) без необходимости использовать полноценный фреймворк.
                                                                                              Я тут не вижу противоречия. Похоже, что мы с вами говорим об одном и том же. Под «оздоровить» я как раз и имел ввиду «выделить ключевую идею и убрать мишуру».
                                                                                              • 0
                                                                                                Под мишурой вы имеете в виду то, что делает Angular фреймворком а не библиотекой как react.js? Ну так в Angular2 уже решили сделать все модульным. То есть начиная с версии 2.0 фреймворк будет полностью разделен на отдельные независимые компоненты (кое какие, например тот же DI, уже доступны и как по мне вполне себе стабильны) и вы будете вольны использовать только то что используете. Меня же устраивает монолитная структура Angular так как я задействую всю эту мишуру (DI, директивы, модули, разделение на этап конфигурации и выполнения и прочую «чушь»).
                                                                                          • +6
                                                                                            О, вы меня сподвигли начать писать статью про vue.js, наконец.
                                                                                            Который при желании может прикидываться и ангуляром, и бэкбоном (в минимальной форме, конечно, но порог входа для тех, кто с ними имел дело, около плинтуса), летает (перфоманс — изумительный). Поддерживается буквально двумя людьми, но при этом мелкие issue-ы, которые я им пишу, например, вечером в четверг, в 6 утра в пятницу оказываются уже исправлены :)

                                                                                            Ну и подход очаровывает.
                                                                                            «DI? да нахрена вам DI в фреймворке для клиентсайда, у тебя есть AMD или CommonJS или что еще придет в твою больную голову»
                                                                                            «Что? Навигация? Чувак, тебе оно точно надо? Посмотри сколько клевых библиотек для навигации и без нашей помощи сделано, мы тебе сделали директиву для смены лейаутов, на здоровье»
                                                                                            «Компоненты? Службы? Модели? Директивы? Сервисы? Чо ты к нам пристал. На тебе фильтры для шаблонов, компоненты для, собственно, автономных компонентов, и директивы для всяких мимимишных жкверишных плагинов твоих, хватит тебе».
                                                                                            И реально хватает ведь.
                                                                                            А что самое крутое — он эти шаблоны свои — ну вот такой, например: {{ profiles[currentUserId] }} — (да-да, привет, ангуляр) он не разворачивает как-то, а превратит в
                                                                                            try {
                                                                                            return this.profiles[this.currentUserId];
                                                                                            } catch (e){
                                                                                            ...
                                                                                            }
                                                                                            

                                                                                            и если флаг debug установлен — он сам вызовет дебаггер на ошибке. А this реально указывает на окружение, которое можно полноценно поинспектировать.
                                                                                            Я так приложение в айфрейме дебажил (был один прикол, связанный с хромовскими приложениями). Как бы я с другими фреймворками это делал — вообще бы не представляю.
                                                                                            • 0
                                                                                              vue штука действительно хорошая и минималистичная.
                                                                                              • 0
                                                                                                Видимо вы не видели обёрток backbone которые пытаются предотвращать утечки, но у них это не очень хорошо получается. И не строили рективных приложений с частыми (50-60 в сек) push-нотификациями с сервера по comet'у или websocket'aм…

                                                                                                Vue.js достаточно простое решение производительность которого под большим вопросом — авторы говорят что сравнивать его с React'ом, Backbone'ом или Angular'ом на данном этапе развития нельзя — слишком разные методы рендеринга, больше меряем производительность браузера нежели фреймворка… хотя на самом деле авторы хотели переплюнуть React, но у них это не получилось и им стыдно стало :3 А вот с тем что с остальным сравнивать бесполезно — там будет разница просто адовая, я вполне согласен.

                                                                                                Но опять же очередное сырое решение не готовое для продакшенов средних размеров.
                                                                                                • +1
                                                                                                  С react-ом — сравнивать вообще что-либо сложно, особенно с react+om.
                                                                                                  А в нынешней версии (0.11.х) почти все детские ошибки исправили. Я за проектом почти год уже слежу и могу на полном серьезе сказать — 99% кейсов покрыто, и неожиданные ошибки в духе «что-то не работает, хотя должно» — на 0.11 у меня ни разу не появлялись. Да, были ляпы, связанные именно с новыми фичами (вот два, которые я закоммитил: #652, #594, например) — но конкретно с работой приложения они уже не были связаны.

                                                                                                  Я бы сказал, что сейчас Vue — medium rare. Да, немного сыроват, но удовольствие от употребления будет наблюдаться у большинства :)

                                                                                                  А насчет 50-60 обновлений в секунду — я в январе за подобный проект берусь. При этом это полноценный энтерпрайз с джавой на бэкенде и прочими удовольствиями жизни. Сейчас думаю над выбором: ангуляр или React+Om. При этом совесть меня склоняет к первому, а предчувствие жопы с перформансом — к второму. О Vue там и речи быть не может, конечно — даже не из соображений того, что он нестабилен так или иначе, а как минимум из-за того, что он поддерживаться будет не один год, и найти разработчиков на vue в дальнейшем будет сложнее, чем на react или angular.
                                                                                                  • 0
                                                                                                    J2EE сервлеты vs Plain Netty это ~35 к 1 по скорости обработки пустых запросов.
                                                                                                    При больших БД, и толстых кэшах нужно внедрять offheap кэширование, можно на hazelcast'е или terracotta'е.
                                                                                                    ClojureScript'овый Om выглядит лично для меня очень небрежно — как если бы elisp с prolog'ом смешали.
                                                                                                    Кроме всего этого нужно ещё внедрять rx.js или highland для отработки асинхрона без лишних проблем.
                                                                                                    • +1
                                                                                                      Да я-то тут при чем. Я фронтэнд обеспечиваю. Я вообще джаву не умею и не хочу уметь (но, видимо, андроида ради и придется когда-нибудь).
                                                                                                      Как специалист я сраный фронтэндщик, который даже верстает медленно, зато умеет в джаваскрипт так, что все вокруг хренеют, на этом мои прикладные способности заканчиваются. То, что я умею дизайн, ux, настраивать nginx, спокойно кодить под рельсы, работать с кучей других языков, читать исходники v8, паять усилители, управлять разработчиками и разбираться в особенностях низкоуровневых протоколов — это круто, но это исключительно жырный плюс к тому, что я хороший фронтэндщик, который понимает как работает все, с чем он взаимодействует — начиная от того, как работают http-запросы на всех уровнях модели OSI и заканчивая тем, как повысить конверсию :) Потому и занимаюсь такими замороченными проектами.
                                                                                                      И вот честно, никакого желания в этот неплохой багаж знаний добавлять особенности работы кэшей под джаву)

                                                                                                      Но про Om запомню, спасибо.
                                                                                                  • 0
                                                                                                    Извините, но что у Вас за задача такая, которая вынуждает слать 50-60 нотификаций в секунду с сервера?
                                                                                                    • 0
                                                                                                      Учёт работы ~400 человек персонала в реальном времени: телефония, консультирование, денежные транзакции, доставка товаров…
                                                                                                      • +3
                                                                                                        Смысла нет так часто слать, раз в секунду достаточно, человек же не машина.
                                                                                                        • 0
                                                                                                          Там очень много данных вбивается и редактируется в реальном времени достаточно большим количеством людей — нужно это всё синхронизировать и формировать Batch запросы на запись в журнал изменений, проставлять временные метки в векторных часах и решать задачу консенсуса (у меня пока raft). Это можно представить как один большой гуглодок с табличками которые очень быстро правят 5-6 человек, и в метериализованном представлении которых постоянно пересчитываются и перепроверяются данные после каждой правки в браузере.
                                                                                                          • 0
                                                                                                            Да, именно поэтому и спросил. Мне сразу представилось перемигивание разных кнопочек и формочек в окне, от которых начинает рябить в глазах. Так и не понял почему нельзя посылать «сумму» изменений к примеру раз в секунду (а то и реже).
                                                                                                  • –3
                                                                                                    Количество плюсов этой статьи напрямую отражает количество дилетантов на хабре, и это печально.
                                                                                                    • –1
                                                                                                      А может некоторые уже давно перешагнули ангуляр? Ну хотя бы разработчики самого ангуляра ;) Версии 2.0. Хотя там вроде даже люди поменялись, но это другое
                                                                                                      • +1
                                                                                                        Для тех, кто перешагнул ангуляр, не составит особого труда погуглить и решить все проблемы описанные в статье.
                                                                                                        • +2
                                                                                                          Автор решил. Не использует ангуляр.
                                                                                                          • +1
                                                                                                            Как по мне это не перешагнуть а сдаться.
                                                                                                            • +4
                                                                                                              как многие сдались c YUI, mootools, prototype etc.
                                                                                                    • +4
                                                                                                      Использую Angular не два года, а всего полгода, но хорошо понимаю автора.

                                                                                                      После известий о Angular 2.0, который всё поломает, я решил посмотреть на что-то другое и сейчас читаю документацию по ember.js — и знаете, СЛЕЗЫ СЧА^W^W слезы счастья катятся по моим щекам. Если кто-то испытывает непонятный баттхерт от прекрасной, как все вокруг говорят, технологии — советую посмотреть на ember.
                                                                                                      • 0
                                                                                                        У ember'a долгое время до первой версии были проблемы с API и сообществом — не было документации нормальной, и обратная совместимость отваливалась от версии до версии. Сейчас это один из ходовых фреймворков без особых заморочек, «который работает». Его задачей было: сохранить простоту, и не раздувать излишне свой функционал. Angular любят за то что там можно писать меньше кода, и от него бывает больше толку. Но шаг влево — шаг вправо, не по гайдлайнам — сразу начинаются приколы. В общем порог вхождения не большой — нужно просто много читать и разбираться, а не писать вот такие вот бесполезные статьи на хабр.
                                                                                                        • 0
                                                                                                          Пишу и на Ember, и на Angular. На Ember у меня всегда меньше кода получается. И самое главное: я могу пересесть с одного Эмберовского проекта на другой без особых разбирательств, а Angular в каждой команде почему-то готовят по-своему и приходится время тратить, чтобы разобраться, какие тут приняты правила и конвенции.
                                                                                                        • +1
                                                                                                          Пишу на Ember. По началу — все радужно. Потом всплывают разные косяки, которые обещают починить в 2.0

                                                                                                          Основное, что считаю поломанным сейчас:
                                                                                                          1. собственно EmberData. Да, оно в бете, и грех жаловаться, но готовьтесь к тому, что: rollback не работает на one-to-one, one-to-many, DataBoundPromise никак не доедут до релиза
                                                                                                          2. документация отличная, но не покрывает все моменты (некоторые вещи приходится смотреть прямо в коде)
                                                                                                          3. многострадальные queryParams. Они вроде как есть, но некоторые вещи в них не работают и на них заведено много issue
                                                                                                          4. синглтон контроллеры настолько всем не нравятся, что их убирают в 2.0
                                                                                                          5. сложно писать сложные компоненты, где требуется обновление большого кол-ва property и не хватает one-way binding property. Новый подход к компонентам обещают в 2.0 (больше похоже на React)

                                                                                                          Что действительно радует — роутер, к нему претензий нет.

                                                                                                          Судя поrfc для 2.0, они хотят с помощью HTMLBars + one-way binding сделать компоненты похожими на React, но при этом использовать всю мощь роутера и EmberData для моделей
                                                                                                          • 0
                                                                                                            По 4му пункту я сейчас обхожусь тем, что пишу без контроллеров. Все контроллеры — автогенеренные Эмбером везде, где можно. По факту пишу свои только если нужны queryParams. Решает кучу проблем.
                                                                                                            • 0
                                                                                                              Это то, к чему они идут в 2.0. Т.е. все property, фильтры и прочее в Route?
                                                                                                          • 0
                                                                                                            Скажите, а зачем вы выбираете инструменты, которые «умеют все»?
                                                                                                            • 0
                                                                                                              А такие существуют?
                                                                                                              • +3
                                                                                                                Я о том, что многие инструменты пытаются добавить все на свете в свой функционал. ИМО это плохо заканчивается.
                                                                                                                • 0
                                                                                                                  Согласен, «разделяй и властвуй».
                                                                                                                  • 0
                                                                                                                    Угу. При чем плохо заканчивается для разработчика/продукта. Вместо замены одного компонента приходится выбрасывать 80% кода при переходе от А к Б.
                                                                                                              • +3
                                                                                                                Вопрос не в том, что инструмент умеет все, а в том, сколько у вас накапливается в проекте кастомного и glue-кода, который ничего не делает кроме как соединять отдельные «идеальные» микро-библиотеки.

                                                                                                                Многие считают:
                                                                                                                1. о, я возьму вот эту микробиблиотеку, соединю вон с той, буду брать все самое лучшее, все то и только то, что подходит для моей задачи, — и получу идеальный проект.
                                                                                                                2. потом в коде для склейки частей у них возникает какое-то дублирование кода, вырисовываются какие-то шаблоны, они их начинают вычленять, радуются, как у них все идеально и идиоматично, и т.д.
                                                                                                                3. так из идеальных кусочков у них получается свой недофреймворк, на котором они пишут свое приложение.
                                                                                                                4. а потом этот фреймворк начинает трещать по швам из-за «особых частных случаев», обхода багов в выбранных библиотеках, несостыковываемостью выбранных компонентов между собой, проблем с производительностью и т.д.
                                                                                                                5. а времени фиксить недофрейсворк нет — проект, сроки, заказчик, менеджер. Взяли человека в команду — ему с ним теперь неделями разбираться. А если «автор» фреймворка уже ушел из команды, и вы — как раз тот человек, кому придется разбираться в костылях вокруг идеальных библиотек образца 2013 года?

                                                                                                                Иногда проще взять готовое большое решение и быстро решить задачу. Плюсы Эмбера:

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

                                                                                                                Он не делает для вас все, но 90% того, что он делает, вам наверняка подойдет.
                                                                                                                • 0
                                                                                                                  Здраствуйте. Что-то просмотрел пост в свое время.

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

                                                                                                                  Что до Эмбера, то ничего не скажу. С виду хороший, во многом наверное лучший фреймворк для многих задач.
                                                                                                            • +6
                                                                                                              Довелось мне как то переписывать код с angular на backbone. Angular не понравился из-за вшитого кода в html. Htmlу и так уже плохо от всяких штук, а тут ещё и angular. Так что я не против angular, но только если мне не придется на нем писать.
                                                                                                              • +2
                                                                                                                «Я не против angular, но только если мне не придется на нем писать» — гениальное выражение :) Его кстати можно применить к вообще любой технологии :)