Вопрос: «Мышление в AngularJS», если у меня есть фон jQuery? [закрыто]


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

  • Как мне по-разному создавать и создавать клиентские веб-приложения? Какая разница?
  • Что я должен прекратить делать / использовать; Что я должен начать делать / использовать вместо этого?
  • Существуют ли какие-либо соображения / ограничения на стороне сервера?

Я не ищу подробного сравнения между jQueryа также AngularJS,


4525


источник


Ответы:


1. Не разрабатывайте свою страницу, а затем меняйте ее с помощью DOM манипуляции

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

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

2. Не увеличивайте jQuery с помощью AngularJS

Точно так же не начинайте с идеи, что jQuery делает X, Y и Z, поэтому я просто добавлю AngularJS поверх этого для моделей и контроллеров. Это действительно соблазняя, когда вы только начинаете, поэтому я всегда рекомендую, чтобы новые разработчики AngularJS вообще не использовали jQuery, по крайней мере, пока они не привыкнут к тому, чтобы делать вещи «Угловой путь».

Я видел много разработчиков здесь и в списке рассылки создаю эти сложные решения с плагинами jQuery из 150 или 200 строк кода, которые затем склеиваются в AngularJS с набором обратных вызовов и $applyкоторые запутывают и запутывают; но в итоге они работают! Проблема в том, что в большинство случаи, когда плагин jQuery можно было переписать в AngularJS во фракции кода, где внезапно все становится понятным и понятным.

Суть в том, что: при решении проблемы сначала «подумайте в AngularJS»; если вы не можете придумать решение, спросите сообщество; если после всего этого нет простого решения, тогда не стесняйтесь обращаться к jQuery. Но не позволяйте jQuery стать костылем, или вы никогда не освоите AngularJS.

3. Всегда думайте об архитектуре

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

Тогда как вы это делаете? Как вы думаете в AngularJS? Вот некоторые общие принципы, в отличие от jQuery.

Представление - это «официальная запись»,

В jQuery мы программно меняем представление. У нас может быть выпадающее меню, определяемое как ulвот так:

<ul class="main-menu">
    <li class="active">
        <a href="#/home">Home</a>
    </li>
    <li>
        <a href="#/menu1">Menu 1</a>
        <ul>
            <li><a href="#/sm1">Submenu 1</a></li>
            <li><a href="#/sm2">Submenu 2</a></li>
            <li><a href="#/sm3">Submenu 3</a></li>
        </ul>
    </li>
    <li>
        <a href="#/home">Menu 2</a>
    </li>
</ul>

В jQuery, в нашей логике приложения, мы активировали бы его с чем-то вроде:

$('.main-menu').dropdownMenu();

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

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

<ul class="main-menu" dropdown-menu>
    ...
</ul>

Эти два делают то же самое, но в версии AngularJS любой, кто смотрит на шаблон, знает, что должно произойти. Всякий раз, когда на борт приходит новый член команды разработчиков, она может смотреть на это, а затем знать что существует директива, называемая dropdownMenuработающий на нем; ей не нужно вводить правильный ответ или просеивать любой код. Взгляд сказал нам, что должно было случиться. Гораздо чище.

Разработчики, новые для AngularJS, часто задают такой вопрос, как: как найти все ссылки определенного типа и добавить на них директиву. Разработчик всегда ошеломлен, когда мы отвечаем: вы этого не делаете. Но причина, по которой вы этого не делаете, это то, что это похоже на half-jQuery, half-AngularJS и ничего хорошего. Проблема здесь в том, что разработчик пытается «выполнить jQuery» в контексте AngularJS. Это никогда не будет хорошо работать. Вид является официальный отчет. Вне директивы (подробнее об этом ниже), вы никогда, никогда, никогда измените DOM. Применяются директивы в представлении , поэтому намерение ясно.

Помните: не разрабатывайте, а затем отмечайте. Вы должны архитектовать, а затем проектировать.

Связывание данных

Это, безусловно, одна из самых удивительных особенностей AngularJS, и вырезает много необходимости делать виды манипуляций с DOM, о которых я упоминал в предыдущем разделе. AngularJS автоматически обновит ваше представление, чтобы вам не пришлось! В jQuery мы отвечаем на события, а затем обновляем контент. Что-то вроде:

$.ajax({
  url: '/myEndpoint.json',
  success: function ( data, status ) {
    $('ul#log').append('<li>Data Received!</li>');
  }
});

Для представления, которое выглядит так:

<ul class="messages" id="log">
</ul>

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

Это немного грязный и мелочный хрупкий. Но в AngularJS мы можем это сделать:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

И наш взгляд может выглядеть так:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

Но в этом отношении наш взгляд может выглядеть так:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

И вместо того, чтобы использовать неупорядоченный список, мы используем ботстрап-оповещения. И нам никогда не приходилось менять код контроллера! Но что более важно, независимо от того, где или как журнал будет обновлен, вид тоже изменится. Автоматически. Ухоженная!

Хотя я не показал его здесь, привязка данных является двусторонней. Таким образом, эти сообщения журнала могут также редактироваться в представлении, только делая это: <input ng-model="entry.msg" />, И было много радости.

Отличный модельный слой

В jQuery DOM похож на модель. Но в AngularJS у нас есть отдельный слой модели, который мы можем управлять любым способом, который мы хотим, полностью независимо от представления. Это помогает для вышеуказанного связывания данных, поддерживает разделение проблем , и вводит гораздо большую тестируемость. Другие ответы упомянули этот момент, поэтому я просто оставлю это.

Разделение проблем

И все вышеперечисленное связывает эту сложную тему: сохраняйте свои проблемы отдельно. Ваше мнение выступает в качестве официального отчета о том, что должно произойти (по большей части); ваша модель представляет ваши данные; у вас есть сервисный уровень для выполнения многоразовых задач; вы выполняете манипуляции с DOM и расширяете свое представление с помощью директив; и вы склеиваете все это вместе с контроллерами. Это было упомянуто и в других ответах, и единственное, что я хотел бы добавить, относится к тестируемости, о чем я расскажу в другом разделе ниже.

Внедрение зависимости

Чтобы помочь нам разобраться в проблемах, внедрение зависимости (ДИ). Если вы используете серверный язык (из Ява в PHP ), вы, вероятно, уже знакомы с этой концепцией, но если вы являетесь клиентским парнем из jQuery, эта концепция может показаться от глупых до избыточных до хипстеров. Но это не так. :-)

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

Скажем, в нашем приложении нам нужна служба, которая реализует серверную память через ОТДЫХ API и, в зависимости от состояния приложения, локальное хранилище. При выполнении тестов на наших контроллерах мы не хотим связываться с сервером - мы тестируем контроллер , в конце концов. Мы можем просто добавить mock-сервис с тем же именем, что и наш оригинальный компонент, и инжектор будет гарантировать, что наш контроллер получит поддельный автоматически - наш контроллер не знает и не нуждается в различии.

Говоря об испытаниях ...

4. Разработка, основанная на испытаниях - всегда

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

Из всех плагинов jQuery, которые вы видели, использовали или писали, сколько из них имело сопутствующий набор тестов? Не очень много, потому что jQuery не очень поддается этому. Но AngularJS есть.

В jQuery единственным способом тестирования является создание компонента независимо с образцовой / демонстрационной страницей, с помощью которой наши тесты могут выполнять манипуляции с DOM. Итак, мы должны разработать компонент отдельно и тогда интегрируйте его в наше приложение. Как неудобно! Так много времени, при разработке с помощью jQuery, мы выбираем итеративный вариант вместо разработки, основанной на тестах. И кто может обвинить нас?

Но поскольку у нас есть разделение опасений, мы можем сделать тестовое развитие итеративно в AngularJS! Например, предположим, что мы хотим, чтобы суперпростая директива указывала в нашем меню, каков наш текущий маршрут. Мы можем заявить, что хотим, с точки зрения нашего приложения:

<a href="/hello" when-active>Hello</a>

Хорошо, теперь мы можем написать тест для несуществующего when-activeдиректива:

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );

    $location.path('/not-matching');
    expect( elm.hasClass('active') ).toBeFalsey();

    $location.path( '/hello' );
    expect( elm.hasClass('active') ).toBeTruthy();
}));

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

.directive( 'whenActive', function ( $location ) {
    return {
        scope: true,
        link: function ( scope, element, attrs ) {
            scope.$on( '$routeChangeSuccess', function () {
                if ( $location.path() == element.attr( 'href' ) ) {
                    element.addClass( 'active' );
                }
                else {
                    element.removeClass( 'active' );
                }
            });
        }
    };
});

Наш тест проходит а также наше меню выполняется в соответствии с запросом. Наше развитие и то и другое итеративный а также тест-привод. Злая-круто.

5. Концептуально, директивы не упакованный jQuery

Вы часто слышите «только манипулирование DOM в директиве». Это необходимость. Относитесь к нему с должным уважением!

Но давайте немного глубже ...

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

AngularJS поставляется со всем набором инструментов, чтобы сделать это очень просто; с ngClassмы можем динамически обновлять класс; ngModelобеспечивает двустороннюю привязку данных; ngShowа также ngHideпрограммно показать или скрыть элемент; и многие другие - включая те, которые мы пишем сами. Другими словами, мы можем сделать все возможное без DOM-манипуляция. Чем меньше манипуляций с DOM, тем легче выполнять тесты, тем легче они стилисты, тем легче они будут меняться в будущем, а тем более их можно использовать и распространять.

Я вижу много разработчиков, новых для AngularJS, с помощью директив, как места для броска кучи jQuery. Другими словами, они думают: «Поскольку я не могу манипулировать DOM в контроллере, я возьму этот код, поставлю его в директиве». Хотя это, безусловно, намного лучше, часто все еще неправильно ,

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

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

.directive( 'myDirective', function () {
    return {
        template: '<a class="btn">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            var on = false;

            $(element).click( function () {
                on = !on;
                $(element).toggleClass('active', on);
            });
        }
    };
});

В этом есть несколько ошибок:

  1. Во-первых, jQuery никогда не требовался. Мы ничего здесь не сделали, и мне нужен jQuery!
  2. Во-вторых, даже если у нас уже есть jQuery на нашей странице, нет причин использовать его здесь; мы можем просто использовать angular.elementи наш компонент по-прежнему будет работать, когда вы попадете в проект, у которого нет jQuery.
  3. В-третьих, даже если предположить, что jQuery был необходимые для этой директивы для работы, jqLite ( angular.element) будем всегда используйте jQuery, если он был загружен! Поэтому нам не нужно использовать $- мы можем просто использовать angular.element,
  4. Четвертое, тесно связанное с третьим, состоит в том, что элементы jqLite не должны быть обернуты в $- elementкоторый передается linkфункция уже элемент jQuery!
  5. И в-пятых, о которых мы упоминали в предыдущих разделах, почему мы смешиваем материал шаблона с нашей логикой?

Эта директива может быть переписана (даже для очень сложных случаев!) Гораздо проще:

.directive( 'myDirective', function () {
    return {
        scope: true,
        template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            scope.on = false;

            scope.toggle = function () {
                scope.on = !scope.on;
            };
        }
    };
});

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

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

w00t!

Так что, если директивы - это не только коллекции функций типа jQuery, каковы они? Директивы на самом деле расширения HTML , Если HTML не делает что-то, что вам нужно для этого, вы пишете директиву, чтобы сделать это за вас, а затем используйте его так же, как если бы он был частью HTML.

Иными словами, если AngularJS ничего не делает из коробки, подумайте, как команда выполнит это, чтобы соответствовать ngClick, ngClass, и другие.

Резюме

Даже не используйте jQuery. Не включайте его. Он вернет вас. И когда вы сталкиваетесь с проблемой, которую, как вы думаете, знаете, как решить в jQuery уже, прежде чем вы $, попробуйте подумать о том, как это сделать в пределах AngularJS. Если вы не знаете, спросите! 19 раз из 20, лучший способ сделать это не нужен jQuery и попытаться решить его с результатами jQuery, чтобы больше работать для вас.


7187



Императивный → декларативный

В jQuery, селекторы используются для поиска DOM элементов, а затем привязать / зарегистрировать обработчики событий. Когда событие запускается, этот (императивный) код выполняет обновление / изменение DOM.

В AngularJS вы хотите подумать о Просмотры а не элементов DOM. Представления (декларативные) HTML, содержащие AngularJS директивы , Директивы настраивают обработчики событий за кулисами для нас и дают нам динамическую привязку данных. Селекторы редко используются, поэтому потребность в идентификаторах (и некоторых типах классов) значительно уменьшается. Представления привязаны к модели (по областям). Представления - это проекция модели. Модели изменения событий (т. Е. Данные, свойства области) и представления, которые проектируют эти модели, обновляются автоматически.

В AngularJS подумайте о моделях, а не о выбранных jQuery элементах DOM, которые хранят ваши данные. Подумайте о представлениях как проекциях этих моделей, а не о регистрации обратных вызовов, чтобы управлять тем, что видит пользователь.

Разделение проблем

Работает jQuery ненавязчивый JavaScript - поведение (JavaScript) отделено от структуры (HTML).

Использование AngularJS контроллеры и директивы (каждый из которых может иметь свой собственный контроллер и / или компилировать и связывать функции), чтобы удалить поведение из представления / структуры (HTML). Угловая также имеет Сервисы а также фильтры чтобы помочь разделить / организовать ваше приложение.

Смотрите также https://stackoverflow.com/a/14346528/215945

Дизайн приложений

Один подход к разработке приложения AngularJS:

  1. Подумайте о своих моделях. Создавайте службы или свои собственные объекты JavaScript для этих моделей.
  2. Подумайте, как вы хотите представить свои модели - ваши взгляды. Создавайте HTML-шаблоны для каждого представления, используя необходимые директивы для получения динамической привязки данных.
  3. Прикрепите контроллер к каждому виду (используя ng-view и routing, или ng-controller). Попросите диспетчера найти / получить только любые данные модели, которые должны выполнять представления. Сделайте контроллеры как можно более тонкими.

Прототипное наследование

Вы можете многое сделать с jQuery, не зная о том, как работает прототипное наследование JavaScript. При разработке приложений AngularJS вы избежите некоторых распространенных ошибок, если у вас есть хорошее понимание наследования JavaScript. Рекомендуемое чтение: Каковы нюансы объема прототипа / прототипного наследования в AngularJS?


408



AngularJS против jQuery

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

Это нормально, вы должны проталкивать. Угловая стоит того.

Большая разница (TLDR)

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

AngularJS вместо этого дает вам компилятор ,

Это означает, что AngularJS читает всю вашу DOM сверху вниз и рассматривает ее как код, буквально как инструкции для компилятора. Когда он пересекает DOM, он ищет конкретные директивы (директивы компилятора), которые сообщают компилятору AngularJS, как вести себя и что делать. Директивы - это небольшие объекты, наполненные JavaScript, которые могут соответствовать атрибутам, тегам, классам или даже комментариям.

Когда компилятор Angular определяет, что часть DOM соответствует определенной директиве, она вызывает директивную функцию, передавая ей элемент DOM, любые атрибуты, текущую $ scope (которая является локальным хранилищем переменных) и некоторые другие полезные биты. Эти атрибуты могут содержать выражения, которые могут быть интерпретированы в Директиве, и которые сообщают ему, как визуализировать, и когда они должны перерисовываться.

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

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

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

Давайте перейдем к первозданности.

Во-первых, Angular не заменяет jQuery

Угловые и jQuery делают разные вещи. AngularJS предоставляет вам набор инструментов для создания веб-приложений. jQuery в основном предоставляет вам инструменты для изменения DOM. Если jQuery присутствует на вашей странице, AngularJS будет использовать его автоматически. Если это не так, AngularJS отправляется с jQuery Lite, который является сокращенной, но все же прекрасно используемой версией jQuery.

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

Если вы используете jQuery, вы не должны разбрызгивать его повсюду. Правильное место для DOM-манипуляции в AngularJS находится в директиве. Подробнее об этом позже.

Ненавязчивый JavaScript с селекторами и декларативными шаблонами

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

JavaScript находится под контролем. HTML имеет совершенно независимое существование. Ваш HTML остается семантическим, даже без JavaScript. Атрибуты Onclick - очень плохая практика.

Одной из первых вещей, которые вы заметите в AngularJS, является то, что пользовательские атрибуты повсюду , Ваш HTML будет усеян атрибутами ng, которые по сути являются атрибутами onClick на стероидах. Это директивы (директивы компилятора) и являются одним из основных способов привязки шаблона к модели.

Когда вы впервые увидите это, у вас может возникнуть соблазн написать AngularJS в качестве старого школьного навязчивого JavaScript (как я сделал сначала). Фактически, AngularJS не играет по этим правилам. В AngularJS ваш HTML5 является шаблоном. Он скомпилирован AngularJS для создания вашей веб-страницы.

Это первая большая разница. Для jQuery ваша веб-страница - это DOM, которым нужно манипулировать. Для AngularJS ваш HTML-код должен быть скомпилирован. AngularJS читает на вашей всей веб-странице и буквально компилирует ее на новую веб-страницу, используя встроенный компилятор.

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

Шаблон находится на водительском сиденье.

Один из первых вопросов, которые я задал себе при запуске AngularJS и запуске учебников, - это «Где мой код?» , Я не написал JavaScript, и все же у меня есть все это. Ответ очевиден. Поскольку AngularJS компилирует DOM, AngularJS обрабатывает ваш HTML как код. Для многих простых случаев достаточно просто написать шаблон и позволить AngularJS скомпилировать его в приложение для вас.

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

Это больше похоже на XSLT чем Рубин на рельсах например.

Это радикальная инверсия управления, к которой привыкает.

Не пытайтесь запустить приложение из своего JavaScript. Пусть шаблон управляет приложением, и пусть AngularJS позаботится о подключении компонентов вместе. Это также Угловой способ.

Семантический HTML против семантических моделей

С jQuery ваша HTML-страница должна содержать семантический значимый контент. Если JavaScript отключен (пользователем или поисковой системой), ваш контент остается доступным.

Потому что AngularJS рассматривает вашу HTML-страницу как шаблон. Шаблон не должен быть семантическим, поскольку ваш контент обычно хранится в вашей модели, которая в конечном итоге исходит из вашего API. AngularJS компилирует вашу DOM с моделью для создания семантической веб-страницы.

Ваш HTML-источник больше не является семантическим, вместо этого ваш API и скомпилированный DOM являются семантическими.

В AngularJS, что означает жизнь в модели, HTML - это просто шаблон, только для отображения.

На данный момент у вас, вероятно, есть всевозможные вопросы, касающиеся SEO и доступность, и это правильно. Здесь есть открытые проблемы. Большинство читателей экрана будут обрабатывать JavaScript. Поисковые системы также могут индексировать AJAXed содержание. Тем не менее, вы захотите убедиться, что используете URL-адреса pushstate, и у вас есть достойная карта сайта. См. Здесь для обсуждения вопроса: https://stackoverflow.com/a/23245379/687677

Разделение проблем (SOC) и MVC

Разделение проблем (SOC) - это шаблон, который вырос за многие годы веб-разработки по разным причинам, включая SEO, доступность и несовместимость браузера. Это выглядит так:

  1. HTML - семантическое значение. HTML должен стоять один.
  2. CSS - Styling, без CSS страница все еще доступна для чтения.
  3. JavaScript - Поведение, без скрипта содержание остается.

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

Это выглядит так:

  1. Модель - ваши модели содержат ваши семантические данные. Модели обычно JSON объекты. Модели существуют как атрибуты объекта с именем $ scope. Вы также можете сохранить удобные функции утилиты в $ scope, доступ к которым могут получить ваши шаблоны.
  2. Вид. Ваши представления написаны в формате HTML. Представление, как правило, не является семантическим, потому что ваши данные живут в модели.
  3. Контроллер. Контроллер - это функция JavaScript, которая перехватывает представление модели. Его функция - инициализировать $ scope. В зависимости от вашего приложения вам может понадобиться создать контроллер или нет. На странице может быть много контроллеров.

MVC и SOC не находятся на противоположных концах одинакового масштаба, они находятся на совершенно разных осях. SOC не имеет смысла в контексте AngularJS. Вы должны забыть об этом и двигаться дальше.

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

Плагины против директив

Плагины расширяют jQuery. Директивы AngularJS расширяют возможности вашего браузера.

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

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

В AngularJS мы определяем директивы. Директива - это функция, которая возвращает объект JSON. Этот объект сообщает AngularJS, какие элементы DOM нужно искать, и какие изменения внесены в них. Директивы привязаны к шаблону с использованием атрибутов или элементов, которые вы изобретаете. Идея состоит в том, чтобы расширить возможности HTML с новыми атрибутами и элементами.

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

Если вам нужна карусель, просто используйте <carousel />элемент, затем определите директиву для вытягивания шаблона и сделайте эту присоску.

Множество небольших директив против больших плагинов с переключателями конфигурации

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

Это ошибка в AngularJS.

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

Пока вы не сделаете небольшое изменение.

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

В AngularJS мы пишем меньшие директивы. Наша директива о выделении была бы смехотворно мала. Он может поддерживать сложенное состояние и предоставлять методы fold (), unlold () или toggle (). Эти методы просто обновили бы $ scope.menu.visible, который является булевым, удерживающим состояние.

Теперь в нашем шаблоне мы можем связать это:

<a ng-click="toggle()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

Нужно обновить при наведении курсора мыши?

<a ng-mouseenter="unfold()" ng-mouseleave="fold()">Menu</a>
<ul ng-show="menu.visible">
  ...
</ul>

Шаблон управляет приложением, поэтому мы получаем гранулярность на уровне HTML. Если мы хотим делать исключения по отдельности, шаблон делает это легко.

Закрытие по сравнению с $ scope

Плагины JQuery создаются в закрытии. Конфиденциальность поддерживается в пределах этого закрытия. Это зависит от вас, чтобы поддерживать свою цепочку видимости в этом закрытии. У вас действительно есть доступ к набору узлов DOM, переданных в плагин jQuery, плюс любые локальные переменные, определенные в закрытии, и любые глобальные переменные, которые вы определили. Это означает, что плагины полностью автономны. Это хорошо, но при создании целого приложения может стать ограничительным. Попытка передачи данных между разделами динамической страницы становится сложной задачей.

У AngularJS есть объекты $ scope. Это специальные объекты, созданные и поддерживаемые AngularJS, в которых вы сохраняете свою модель. В некоторых директивах будет появляться новая область $, которая по умолчанию наследует от своей оболочки $ scope с использованием прототипа наследования JavaScript. Объект $ scope доступен в контроллере и в представлении.

Это умная часть. Поскольку структура наследования $ scope наследует структуру DOM, элементы имеют доступ к своей собственной области видимости и любые содержащиеся в ней области, вплоть до глобальной области $ (которая не совпадает с глобальной областью).

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

Это может показаться сложным, на самом деле, как только вы расслабитесь, это похоже на полет. Вам не нужно создавать объект $ scope, AngularJS создает экземпляр и настраивает его для вас правильно и правильно на основе иерархии шаблонов. AngularJS затем делает его доступным для вашего компонента, используя магию инъекции зависимостей (подробнее об этом позже).

Изменения вручную DOM и привязка данных

В jQuery вы делаете все свои изменения DOM вручную. Вы программируете новые элементы DOM. Если у вас есть массив JSON и вы хотите поместить его в DOM, вы должны написать функцию для генерации HTML и вставить ее.

В AngularJS вы тоже можете это сделать, но вам рекомендуется использовать привязку данных. Измените свою модель, и поскольку DOM привязан к ней с помощью шаблона, ваш DOM будет автоматически обновляться, никаких вмешательств не требуется.

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

<input ng-model="user.name" />

Привязывает элемент ввода к $scope.user.name, Обновление ввода обновит значение в вашей текущей области и наоборот.

Точно так же:

<p>
  {{user.name}}
</p>

выведет имя пользователя в абзаце. Это живая привязка, поэтому, если $scope.user.nameзначение обновляется, шаблон также будет обновляться.

Ajax все время

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

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

Объекты обслуживания и вспомогательные функции

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

AngularJS предоставляет нам объекты обслуживания.

Услуги - это простые объекты, которые содержат функции и данные. Они всегда одиночные, то есть никогда не может быть более одного из них. Скажем, мы хотим получить доступ к API переполнения стека, мы можем написать StackOverflowServiceкоторый определяет методы для этого.

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

Сервисные объекты являются автономными компонентами AngularJS, которые мы можем использовать и повторно использовать по своему усмотрению. Это простые объекты JSON, содержащие функции и данные. Они всегда одиночные, поэтому, если вы храните данные на службе в одном месте, вы можете получить эти данные в другом месте, просто запросив ту же службу.

Внедрение зависимости (ДИ) против инкорпорирования - ака-де-спагеттификация

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

Пока вы не начнете использовать это, трудно объяснить, что такое огромное время. В jQuery нет ничего подобного AngularJS DI.

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

Скажем, у меня есть компонент под названием «FlickrService», который определяет методы для вытаскивания JSON-каналов из Flickr. Теперь, если я хочу написать контроллер, который может получить доступ к Flickr, мне просто нужно обратиться к «FlickrService» по имени, когда я объявляю контроллер. AngularJS позаботится о том, чтобы создать экземпляр компонента и сделать его доступным для моего контроллера.

Например, здесь я определяю службу:

myApp.service('FlickrService', function() {
  return {
    getFeed: function() { // do something here }
  }
});

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

myApp.controller('myController', ['FlickrService', function(FlickrService) {
  FlickrService.getFeed()
}]);

AngularJS признает, что объект FlickrService необходим для создания экземпляра контроллера и предоставит его для нас.

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

Модульная архитектура обслуживания

jQuery очень мало говорит о том, как вы должны организовать свой код. У AngularJS есть мнения.

AngularJS предоставляет вам модули, в которые вы можете разместить свой код. Если вы пишете сценарий, который говорит с Flickr, например, вы можете создать модуль Flickr для переноса всех связанных с Flickr функций. Модули могут включать в себя другие модули (DI). Основное приложение обычно является модулем, и это должно включать все другие модули, от которых зависит ваше приложение.

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

Модули содержат компоненты AngularJS. Когда мы включаем модуль, все компоненты в этом модуле становятся доступными для нас как простой список, идентифицированный их уникальными строками , Затем мы можем вставлять эти компоненты друг в друга с использованием механизма впрыска зависимостей AngularJS.

Подводить итоги

AngularJS и jQuery не являются врагами. Можно использовать jQuery в AngularJS очень хорошо. Если вы хорошо используете AngularJS (шаблоны, привязка данных, $ scope, директивы и т. Д.), Вы найдете много меньше jQuery, чем вы могли бы потребовать.

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

Подумайте меньше о ненавязчивом JavaScript и вместо этого подумайте о расширениях HTML.

Моя маленькая книга

Я очень рад AngularJS, я написал короткую книгу, в которой вы можете читать онлайн http://nicholasjohnson.com/angular-book/ , Надеюсь, это полезно.


184



Can you describe the paradigm shift that is necessary?

Imperative vs Declarative

With jQuery you tell the DOM what needs to happen, step by step. With AngularJS you describe what results you want but not how to do it. More on this here. Also, check out Mark Rajcok's answer.

How do I architect and design client-side web apps differently?

AngularJS is an entire client-side framework that uses the MVC pattern (check out their graphical representation). It greatly focuses on separation of concerns.

What is the biggest difference? What should I stop doing/using; what should I start doing/using instead?

jQuery is a library

AngularJS is a beautiful client-side framework, highly testable, that combines tons of cool stuff such as MVC, dependency injection, data binding and much more.

It focuses on separation of concerns and testing (unit testing and end-to-end testing), which facilitates test-driven development.

The best way to start is going through their awesome tutorial. You can go through the steps in a couple of hours; however, in case you want to master the concepts behind the scenes, they include a myriad of reference for further reading.

Are there any server-side considerations/restrictions?

You may use it on existing applications where you are already using pure jQuery. However, if you want to fully take advantage of the AngularJS features you may consider coding the server side using a RESTful approach.

Doing so will allow you to leverage their resource factory, which creates an abstraction of your server side RESTful API and makes server-side calls (get, save, delete, etc.) incredibly easy.


152



To describe the "paradigm shift", I think a short answer can suffice.

AngularJS changes the way you find elements

In jQuery, you typically use selectors to find elements, and then wire them up:
$('#id .class').click(doStuff);

In AngularJS, you use directives to mark the elements directly, to wire them up:
<a ng-click="doStuff()">

AngularJS doesn't need (or want) you to find elements using selectors - the primary difference between AngularJS's jqLite versus full-blown jQuery is that jqLite does not support selectors.

So when people say "don't include jQuery at all", it's mainly because they don't want you to use selectors; they want you to learn to use directives instead. Direct, not select!


84



jQuery

jQuery makes ridiculously long JavaScript commands like getElementByHerpDerp shorter and cross-browser.

AngularJS

AngularJS allows you to make your own HTML tags/attributes that do things which work well with dynamic web applications (since HTML was designed for static pages).

Edit:

Saying "I have a jQuery background how do I think in AngularJS?" is like saying "I have an HTML background how do I think in JavaScript?" The fact that you're asking the question shows you most likely don't understand the fundamental purposes of these two resources. This is why I chose to answer the question by simply pointing out the fundamental difference rather than going through the list saying "AngularJS makes use of directives whereas jQuery uses CSS selectors to make a jQuery object which does this and that etc....". This question does not require a lengthy answer.

jQuery is a way to make programming JavaScript in the browser easier. Shorter, cross-browser commands, etc.

AngularJS extends HTML, so you don't have to put <div> all over the place just to make an application. It makes HTML actually work for applications rather than what it was designed for, which is static, educational web pages. It accomplishes this in a roundabout way using JavaScript, but fundamentally it is an extension of HTML, not JavaScript.


69



jQuery: you think a lot about 'QUERYing the DOM' for DOM elements and doing something.

AngularJS: THE model is the truth, and you always think from that ANGLE.

For example, when you get data from THE server which you intend to display in some format in the DOM, in jQuery, you need to '1. FIND' where in the DOM you want to place this data, the '2. UPDATE/APPEND' it there by creating a new node or just setting its innerHTML. Then when you want to update this view, you then '3. FIND' the location and '4. UPDATE'. This cycle of find and update all done within the same context of getting and formatting data from server is gone in AngularJS.

With AngularJS you have your model (JavaScript objects you are already used to) and the value of the model tells you about the model (obviously) and about the view, and an operation on the model automatically propagates to the view, so you don't have to think about it. You will find yourself in AngularJS no longer finding things in the DOM.

To put in another way, in jQuery, you need to think about CSS selectors, that is, where is the div or td that has a class or attribute, etc., so that I can get their HTML or color or value, but in AngularJS, you will find yourself thinking like this: what model am I dealing with, I will set the model's value to true. You are not bothering yourself of whether the view reflecting this value is a checked box or resides in a td element (details you would have often needed to think about in jQuery).

And with DOM manipulation in AngularJS, you find yourself adding directives and filters, which you can think of as valid HTML extensions.

One more thing you will experience in AngularJS: in jQuery you call the jQuery functions a lot, in AngularJS, AngularJS will call your functions, so AngularJS will 'tell you how to do things', but the benefits are worth it, so learning AngularJS usually means learning what AngularJS wants or the way AngularJS requires that you present your functions and it will call it accordingly. This is one of the things that makes AngularJS a framework rather than a library.


61



Those are some very nice, but lengthy answers.

To sum up my experiences:

  1. Controllers and providers (services, factories, etc.) are for modifying the data model, NOT HTML.
  2. HTML and directives define the layout and binding to the model.
  3. If you need to share data between controllers, create a service or factory - they are singletons that are shared across the application.
  4. If you need an HTML widget, create a directive.
  5. If you have some data and are now trying to update HTML... STOP! update the model, and make sure your HTML is bound to the model.

46