Пользователь
0,5
рейтинг
14 августа 2012 в 23:51

Разработка → Обзор JS-фреймворков. Путешествие через джунгли JavaScript MVC. Ч. 1 перевод

(от 27 июля 2012)
При написании нативного веб-приложения легко начать чувствовать себя богом, способным работать просто с библиотекой работы с DOM (такой как jQuery) и горсткой сервисных плагинов. Вскоре возникает проблема в виде груды вложенных возвратных функций jQuery и разбросанных DOM-элементов без всякой структуры вместо приложения.

Короче, мы застреваем в спагетти-коде. К счастью, есть современные JS-фреймворки (библиотеки, задающие, кроме функций, правила организации кода --прим. перев.), помогающие поддерживать структуру и организованность в проекте, облегчающие ремонтопригодность в будущем.

■ Что такое MVC или, лучше сказать, MV*?


Эти современные библиотеки дают разработчикам простой путь к организации кода, используя вариации паттерна проектирования, известного как MVC (Model-View-Controller). MVC разделяет задачи в приложении на 3 части:

    Модель (логика) представляют проблемно-ориентированные знания и данные в приложении. Думайте о них как о типе данных, которые сможете смоделировать, о таких, как Пользователь, Фото, или Замечание. Модели должны информировать о чём-либо при наблюдении за их текущим состоянием.

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

    Контроллеры (диспетчеры) обрабатывают входные данные (клики, пользовательские действия) в приложении, а Представления можно рассматривать как выходной продукт обработки. Когда Контроллер меняет состояние Модели (например, редактирование заголовка на фото), он прямо не меняет Представление. Это — случай, где работают отношения Модели и Представления.

MVC-фреймворки на Javascript, помогающие в структурировании кода, не всегда строго следуют описанному образцу. У некоторых Контроллер будет отвечать за Представление (backbone.js), самоуверенно смешивая компоненты, считая, что так пока будет лучше.

Поэтому мы именуем такие фреймворки паттернами MV*, то есть, Представление и Модель, скорее всего, будут, но к ним добавится что-то другое (чем просто Контроллер --прим. перев.).

Замечание. существует вариант MVC под названием MVP (Model — View — Presenter) и MVVM (Model — View — ViewModel). Если Вы плохо знакомы с этими понятиями и противитесь принять их на веру, не волнуйтесь. Понадобится время, чтобы освоиться с паттернами; я написал побольше о них в моем онлайн-учебнике "Learning JavaScript Design Patterns" на случай, если Вам понадобится помощь.

■ Когда нам нужен MV*-фреймворк JS?


При построении одностраничного приложения или при создании сложного пользовательского интерфейса, или просто при сокращении количества HTTP-запросов вы, вероятно изобретёте много частей структуры MV*-фреймворка типа Backbone или Ember.

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

Есть нечто намного большее в структурированных приложениях, чем связывание манипуляций DOM, шаблонизации и выявление связей. Зрелые фреймворки MV* обычно не только содержат много кусочков, которые вы бы написали, но и содержат решения будущих задач. Это экономит время, что нельзя недооценивать.

■ Где же мы будем нуждаться в MV*, а где нет?


Если вы пишете приложение для общения с API или для обработки данных бекенда, где основная тяжесть просмотра или управления данными будет в браузере, в нём JavaScript MV*-фреймворк будет полезным.

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

Но если вы строите приложение, которому требуется сервер для большого объёма Представлений (страниц) и используете небольшой JavaScript или jQuery для обмена, паттерн MV может стать убийственным. Конечно, есть сложные приложения в вебе, где частичный показ представлений МОЖЕТ хорошо жить вместе с одностраничным приложением, но для всего остального лучше выбрать механизм загрузки попроще.

■ Проблема выбора: слишком много вариантов?


За последние несколько лет сообщество JavaScript переживало что-то вроде Ренессанса, строя всё более сложные и объёмные приложения. Их стиль всё ещё сильно отличается от классических Архитектур Программного Обеспечения, которые построены на языках C++, Java, которые тоже применяются в вебе наряду с языками для веб-разработки (PHP, Пайтон, .Net и т.д). Как следствие, представления о строительстве приложений мы часто заимствуем из увиденного в других языках.

В моем топике “Классификация JavaScript MVC: Злоупотребление или Развитие?(англ.), я поднял вопрос о том, что сейчас есть слишком большой выбор инструментов для структурирования вашего JS-приложения. Часть проблемы истекает из того, как различные разработчики JavaScript выбирают организацию масштабируемого приложения: MVC, MVP, MVVM? Или что-то другое? Каждую неделю с большим избытком рождаются новые MV*-фреймворки, потому что мы всё ищем “правильный путь”, если он существует вообще. Много разработчиков полагают, что его нет.

Мы идём выбирать новые фреймворки, которые часто возникают как ‘Yet Another Framework Syndrome’ (или YAFS). На правах инноваций кое-что, конечно, приветствуется, но YAFS может привести к большой растерянности и фрустрации, когда разработчики хотят начать писать приложение, а им надо вручную оценить 30 инструментов, чтобы выбрать что-нибудь не сильно неподходящее. Различия между некоторыми фреймворками будут очень тонкими, если не трудноразличимыми.

■ TodoMVC: общее приложение для обучения и сравнения


(Была в апреле заметка на русском: habrahabr.ru/post/142301 )

Мы видим огромный бум в количестве таких MV*-фреймворков за последние несколько лет.

Backbone.js, Ember.js, AngularJS, Spine, CanJS… Список новых и работоспособных решений растёт каждую неделю; разработчики могут быстро потеряться в море вариантов. Им есть из чего выбирать. Имеется много сильных конкурирующих решений от умов, работавших над сложными приложениями, которые вдохновили на создание библиотек (такие как Yehuda Katz и Джереми Ashkenas). Вопрос: что использовать и как выбирать?

Мы осознали это положение и захотели помочь разработчикам максимально упростить процесс выбора. Мы создали TodoMVC — проект, который реализует одно и то же приложение Todo на различных популярных на сегодня MV*-фреймворках. Считайте его измерителем скорости работы с данными для фреймворков. Реализации живут и работают одинаково и помогают нам сравнивать синтаксис и структуру различных фреймворков; таким образом, мы можем выбрать тот, который чувствуется самым удобным или, по крайней мере, сравнение поможет сузить круг выбора.
  

На этой неделе (14 июл.2012) мы выпускаем совершенно новую версию TodoMVC, подробности которой приводятся ниже в разделе приложений.

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

■ Предложенные нами критерии выбора фреймворка


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

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

    Был ли проверен фреймворк в работе?
    Есть ли разработчики, построившие и внедрившие большие, публично доступные приложения с этой библиотекой? Backbone имеет серьёзный список таких (SoundCloud, LinkedIn), но не все имеют подобное. Ember работает в ряде больших приложений, включая инструменты пользователя в Square. JavaScriptMVC используется в крупных приложениях в IBM, не считая других мест. Важно не только знать, что фреймворк работает, но и иметь возможность смотреть на реальный код и понимать, как это может быть построено.

    Фреймворк отработан?
    Мы рекомендуем разработчикам не просто “выбрать это и пойти работать”. Новые проекты часто сопровождаются множеством обсуждений релизов, не забудьте о них, выбирая релиз для приложения продакшн-уровня. Вы же не хотите иметь в проекте риск быть остановленным из-за срочного рефакторинга или других поломок, которые более предсказуемы, если фреймворк отработан, отлажен. Зрелые проекты обычно лучше документированы, официально или через сообщество.

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

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

    Есть ли полная документация?
    Хотя демо-приложения полезны для ссылки и просмотра, вы почти всегда будете общаться с официальными разработчиками фреймворка, узнавать, о поддержке API, о том, как решать общие задачи, как создавать компоненты и какие есть замеченные баги. Любой стОящий фреймворк должен иметь подробную документацию, помогающую разработчикам разобраться в нём. Без неё вы можете найти IRC-каналы с группами разработчиков или проводить самостоятельные исследования, которые сами по себе прекрасны, но часто отнимают много времени по сравнению с заранее предоставленным набором документов.

    Каков объём фреймворка, способность к минификации, сжатию, модульности?

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

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

■ Dojo и усложнение фреймворков на JavaScript


Как многие знают, Dojo Toolkit была одной из первых попыток дать разработчикам средство разработки сложных приложений. Некоторые могут сказать, что это вдохновило их больше думать о задачах для необычных приложений. Я спрашивал [в письме] разработчиков DojoDylan Schiemann, Kitson Келли, и Джеймса Томаса, что они думают о появлении MV*-фреймворков.

В.: Библиотека Dojo не могла всё это решить? Почему она не стала предпочтительным решением для желающих построить более структурированные и нетривиальные приложения?

О.: Несколько лет назад, когда окружение JavaScript развилось от добавления простого Ajax и эффектов на странице, Dojo проповедовал «инструментальный» подход к построению сложных приложений в Вебе.

Многие из тех функций были далеко впереди большинства потребностей разработчиков. С появлением браузера как доминирующей платформы приложения, многие новшества ввели в Dojo Toolkit, а теперь они появляются в новых инструментах. MVC был просто ещё одним пакетом, который предоставляла Dojo достаточно долгое время вместе с другими модулями кода: OOП в JS, виджетов UI, кроссбраузерной графики, шаблонов, интернационализации, доступа к данным, хранилищ данных, тестовых фреймворков, сборки системы и очень многого другого.

Джаваскрипт-библиотеки не должны иметь «претензии», почему Dojo с ранней стадии сконцентрировала усилия на полном цикле разработки приложений уровня предприятия. Тот же фокус имеется сейчас и у MVC, просто это один «инструмент из набора».

Почему Dojo — не доминирующий набор инструментов? Её цель никогда не состояла в том, чтобы стать единственным выбором. Цель была в том, чтобы обеспечить открытый набор инструментов, могущих работать с чем-нибудь другим в пределах проектов и с переносимостью в другие проекты. Dojo критиковалась за то, что была медленной и даже после того, как за это взялись, она критиковалась за то, что была медленной. Попытка избавиться от ярлыка — сложная задача. Трудно документировать особенности богатого набора инструментов. В Dojo 1.8 — 175 суб-пакетов и более 1 400 модулей.

Это не только вопрос о достижении цели документирования, он значит, что Dojo решает не одну задачу. Хорошо, когда вы пишете программу, но очень трудно сначала выяснить, с чего начать. Улучшенная документация и обучающие программы пытаются помочь в работе с Dojo 1.8.

В.: Почему разработчики должны выбрать Dojo и какой список идей вы имеете для будущего проекта? Говорят, что после 1.8 будет другая цель.

О.: В Dojo 1.8 пакет dojox/mvc делает ещё один шаг к зрелости. Много было затрачено времени, усилий, тестирования и внимания сообщества к пакету. Он специализируется на предоставлении модели MVC, усиливающей остальную часть Dojo. Вместе с прикладным пакетом dojox/app для построения rich-приложений для десктопов и мобильных устройств, это делает целостную систему для клиентской стороны.

И это — только один из жизнеспособных путей построения приложений в типичном подходе Dojo.

В 1.8, мало того, что подмодуль MVC становится более зрелым, он основан на устойчивом фреймворке. Это не только дает язык разметки, чтобы создать Ваши View-компоненты, выразить Ваши модели или разработать контроллер. Это намного больше, чем просто подключить ещё один модуль к источнику данных. Поскольку это подключено к остальной части Dojo, вы можете подключить всё, что потребуется.

В Dojo 2.0 мы будем пробовать поднять модульность на новый уровень, чтобы стало еще проще взять то, другое и собрать всё это вместе. Мы также исследуем концепцию изоморфизма, чтобы для пользователя не имело значения, где выполняется код, на клиенте или сервере, и, в конечном счете, это должно быть прозрачно разработчику.

■ Коллекция TodoMVC


В нашем совершенно новом выпуске теперь имеются реализации Todo для самых популярных фреймворков с большим количеством других умеренно используемых фреймворков, запущенных в Labs. Эти реализации прошли много пересмотров, часто принимая «на борт» подсказки из лучших практик и предложения от авторов фреймворка, участников его разработки и пользователей сообщества.
  
Вслед за комментариями, сделанными автором Backbone.js Jeremey Ashkenas и Yehuda Katz, TodoMVC теперь тоже предлагает соответствующие реализации, сделанные на официальной спецификации приложения, такие как навигация (или управление состояниями). (?)

Мы не делаем вид, что более сложные приложения для сравнения невозможны (конечно, возможны), но простота приложения Todo позволяет разработчикам воспринимать структуру кода, синтаксис компонентов и «чувство потока» в достаточной степени, чтобы начать сравнивать фреймворки и смотреть детали их решений или нескольких решений.

Наши приложения включают:

Для интересующихся AMD-версиями:

Наши Labs содержат:
Замечание. Мы сделали одну версию нашего приложения Todo на чистом JavaScript, и другую, с использованием, прежде всего, подхода jQuery. Как видно, эти приложения функционально эквивалентны тому, что написано с фреймворками MVC, но нет никакого разделения задач, и код становится труднее читать и поддерживать по мере роста объёма.
Считаем за честь, что в прошлом году некоторые авторы фреймворков вовлекли нас в обсуждения о том, как улучшить их решения, помогая свести наш опыт с множественным решением в таблицу. Кроме того, мы медленно двинулись к TodoMVC, которое было почти приложением де-факто; добавили новые фреймворки, что означает, что стало легче делать начальные сравнения.

(Тут придётся остановиться на самом интересном месте — размер текста растёт — чтобы прекратить дозволенные речи. Сразу после перерыва будет задан самый ожидаемый вопрос современности: какой фреймворк когда следует использовать? 9 восхитительных одноблочных сентенций, обёрнутых фразой «Я хочу...», завершённые умопомрачительным соусом «Используйте ...!» в рецептах от самого Эдди Османи!)
Далее, в заключительной части:
■ Какой фреймворк когда следует использовать?
■ Что разработчики думают о самых популярных фреймворках? («за» и «против»)
■ Не бойтесь экспериментировать
■ Выход за пределы MV*
■ Заключение.

Похожий обзор: Rich JavaScript Applications – the Seven Frameworks (Throne of JS, 2012), Steven Sanderson, 1th Aug 2012. Различия и совпадения подходов Backbone, Meteor, Ember, AngularJS, Knockout, Spine, Batman, CanJS — по результатам конференции «Throne of JS, 2012».

(Продолжение: 2-я заключительная часть.)
Перевод: Эдди Османи
spmbt @spmbt
карма
157,5
рейтинг 0,5
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

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

  • +4
    Объявлена неделя Javascript на хабре, количество постов и опыта увеличивается вдвое :)
    • +4
      И за кадром звук из героев III, означающий новую неделю )
    • –4
      Популяция Javascript-кодеров увеличивается вдвое ;-)
  • 0
    посмотрел в код примера на jquery и ощутил себя лузером…
    • 0
      А что там сложного?
      • 0
        Скорей всего имеется ввиду организация кода — все на своем месте, оптимизировано обращение к селекторам и т.д.
      • 0
        сложного ничего, но сама структурированность и построение кода… Если вы так пишите — очень вам завидую :)
        • 0
          на самом деле подход не сказать чтобы очень клевый, так писать не стоит
          • 0
            поделитесь методиками как лучше, буду благодарен :)
            • 0
              Сам не знаю как истинно верно :)
              Но выносить абсолютно все в разные методы ненужного объекта без какой-нибудь необходимости не стоит точно.
              • 0
                Отчего же не стоит? Код структурирован, объект содержит необходимые поля и методы. Тут ещё дело вот в чём — самого кода на полторы сотни строк — кот наплакал. Даже стыдно сделать тяп-ляп. Да и не получится — весь код не просто в память (человеческую) помещается, но и даже на 2 экрана.

                Вот тут внутри организовано всё точно также, только немного сложнее структура + используются конструкторы и т.д.

                • +2
                  Не стоит потому что объект не нужен. Создавать объект только ради того, чтобы дернуть у него метод init — это рак мозга.
                  Еще больший рак мозга, к примеру, метод объекта blurOnEnter, который нужен как обработчик собырия keypress в одном из полей. Это просто мешанина ненужных методов, которые никак не связаны с объектом. Можно сказать что это не просто полезный объект, а неймспейс с кучей мусорных функций.

                  Все это дело можно написать гораздо «более лучше» при сохранении компактности.
                  • +1
                    > Все это дело можно написать гораздо «более лучше» при сохранении компактности.
                    Ммм? Написать можно кучей разных способов, никто не спорит. Однако — неужели Вы спорите о необходимости группировать методы для работы с сущностями в объекты/коллекции и т.д.? Либо Ваш путь — спагетти с навешиванием обработчиков обычной простынёй кода?

                    > Создавать объект только ради того, чтобы дернуть у него метод init — это рак мозга.
                    Рак мозга — не посмотреть что метод init() это просто точка входа, которая инициализирует переменные, развесит обработчики и спокойно завершится. А вот обработчики — методы данного объекта (что какбе логично) — просто функции, которые у Вас лежали бы в многострадальном window захламляя его.
                    • 0
                      Вы такой странный, даже код мой не видели, а уже все про него знаете ;)
                      Мой путь — красивый код.

                      Закончим на этом бесполезную дискуссию.
                      • 0
                        Без проблем!
  • 0
    Спасибо за статью, как раз собирался взяться изучать javascript-фреймворк, а тут вы в помощь! Спасибо
  • +2
    Поглядел код на всех этих фреймворках (кроме кофе и джавы — их поверхностно). Полного оху… офигения и вылезания глаз из орбит не вызвал только код KnockoutJS и «голый» на jQuery. Все остальные тако-о-ой лес городят, что страшно становится. Когда вместо однострочного if навешивается гора байндингов, фильтров и прочего — хочется выть.

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

    На самом сайте не хватает перекрёстных ссылок: на страничке примера хорошо бы давать ссылку на код, а во все папки с кодом положить readme, где первая ссылка — на рабочий пример. Ходить параллельно не очень удобно.

    Пойду погляжу примеры из Labs…
    • 0
      Мне кажется, что на примере такого простого приложения, использование данных фреймворков действительно выглядит как стрельба из пушки по воробьям, но если воспринимать в контексте большого приложения, то затраты на писанину окупятся легкостью доработки и ведения проекта.
      • +1
        Я могу понять нагромождение классов и прочие особенности сложных приложений, но всё-таки простые вещи в сложных фреймворках должны делаться просто, безо всяких переподвыподвертов, хаков и кучи инфраструктурного кода. Например, вот код из Dojo:

        define(["dojo/_base/declare", "dojox/mvc/StatefulModel", "todo/store/LocalStorage", "dojox/mvc", "dojo/_base/lang", "dojo/_base/array"],
            function(declare, StatefulModel, LocalStorage, mvc, lang, array) {
            return declare([StatefulModel], {
                data: {
                    id: "todos-dojo",
                    todos : [],
                    incomplete: 0,
                    complete: 0
                },
                store: new LocalStorage(),
                constructor: function () {
                    var data = this.store.get(this.data.id) || this.data;
                    this._createModel(data);
                    this.setUpModelBinding();
                    this.updateTotalItemsLeft();
                },
                setUpModelBinding: function () {
                    mvc.bind(this.incomplete, "value", this.complete, "value", lang.hitch(this, function (value) {
                        return this.todos.get("length") - value;
                    }));
                    array.forEach(this.todos, lang.hitch(this, "bindItemProps"));
                    this.todos.watch(lang.hitch(this, "onTodosModelChange"));
                },
                bindItemProps: function (item) {
                    mvc.bindInputs([item.completed], lang.hitch(this, "updateTotalItemsLeft"));
                    mvc.bindInputs([item.title], lang.hitch(window, setTimeout, lang.hitch(this, "deleteEmptyTasks")));
                },
                deleteEmptyTasks: function () {
                    var len = this.todos.length, idx = 0;
                     while (idx < len) {
                         if (!this.todos[idx].title.value.length) {
                             this.todos.remove(idx);
                             len--;
                             continue;
                         }
                         idx++;
                     }
                },
                onTodosModelChange: function (prop, oldValue, newValue) {
                    this.updateTotalItemsLeft();
                    if (typeof prop === "number" && !oldValue && newValue) {
                        this.bindItemProps(newValue);
                    }
                },
                updateTotalItemsLeft: function () {
                    this.incomplete.set("value", array.filter(this.todos, function (item) {
                        return item && !item.completed.value;
                    }).length);
                }
            });
        });
        


        Это — код модели. В «голом» jQuery мы не даём ввести пустой элемент (if (!$.trim($input.val())) return), здесь пишем вручную какой-то маловменяемый процедурный (ни разу не декларативный!) фильтр и прикручиваем его какой-то трёхуровневой конструкцией с байндингами. В «голом» jQuery мы проходимся по коллекции и считаем количество, здесь делаем то же самое, но с байндингами, хитрым чтением свойств и проверками, что элемент — это элемент (return item && !item.completed.value).

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

        Я ещё молчу про фреймворки, где под каждый элемент управления (кнопка, строчка таблицы и т.п.) пишется отдельный класс.
  • 0
    А кто подскажет, как backbone заставить работать только с POST/GET запросами к серверу?
  • 0
    > Предложенные нами критерии выбора фреймворка
    Есть ещё один критерий, про который большинство почему-то или забывают, или игнорируют.
    А именно возможность «контроллерам» фреймворка использовать в качестве view не только собственные шаблоны, но и уже отрендеренный html код.
    Во-первых, это необходимо для seo, когда контент страниц должен быть доступен поисковикам. На клиент-сайд MVC архитектуре ведь можно строить не только интерфейсы различных сервисов, которым индексация ни к чему, но и всё остальное разннообразие веб сайтов.
    Во-вторых, это может понадобиться для большого объёма данных, когда рендеринг всего на яваскрипте оказывается слишком медленым. Тут пожалуй, наиболее простой пример — это отображение десятков-сотни-другой комментариев к чему-либо.

    И если учитывать этот критерий, то очень многие mvc фреймворки можно сразу отбрасывать, в первую очередь, пожалуй, большинство имеющих data-binding.

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