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


4514

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

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

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


Для тех, кто знаком с "ASP.NET MVC" или "RoR" - просто подумайте об Angular как о "клиентской MVC" и все.
Серж Шульц

Ответы:


7178

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

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

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

2. Не увеличивайте JQuery с AngularJS

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

Я видел много разработчиков здесь и в списке рассылки, которые создавали эти сложные решения с помощью плагинов 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>

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

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

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

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

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

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

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

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

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

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

Кстати о тестировании ...

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="https://stackoverflow.com/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 даст вам больше работы.


204
Я думаю, что включение работы с JQuery в угловое приложение является важным вариантом использования из-за всех существующих плагинов JQuery, которые были написаны. Я не переписываю FancyBox в jQuery, чтобы сохранить чистое приложение Angular.
Таудеп

119
@taudep Я не думаю, что мы не согласны так сильно, как вы думаете. Большинство плагинов jQuery можно дешево переписать в AngularJS, и в таких случаях мы должны это сделать. Для чего-то сложного, для которого нет эквивалента, тогда сделайте это. Цитата из Раздела 2: «Суть в следующем: при решении сначала« думай в AngularJS »; если вы не можете придумать решение, спросите сообщество; если после всего этого нет простого решения, тогда не стесняйтесь обращаться к jQuery . Но не позволяйте jQuery стать опорой, иначе вы никогда не овладеете AngularJS ». [выделение добавлено]
Джош Дэвид Миллер

67
китайский перевод на этот великий ответ, надеюсь, полезно. hanzheng.github.io/tech/angularjs/2013/10/28/…
Хан Чжэн

18
@Benno Под «отсутствием манипуляций с DOM» он подразумевает, что ваш код в директиве не выполняет напрямую манипуляции с DOM. Этот код ничего не знает о DOM, он просто изменяет переменные js в вашей модели. Да, конечный результат заключается в том, что DOM модифицируется, но это потому, что вне кода, который мы пишем, есть привязки, которые реагируют на изменение наших переменных, но внутри директивы мы ничего не знаем об этом, делая четкое разделение между манипулированием DOM и бизнес логика В вашем примере с jQuery вы напрямую изменяете DOM, говоря «добавьте этот текст к этому элементу»
wired_in

11
@trusktr Если разработать когда - либо устанавливает значение входного элемента с помощью JQuery в приложении AngularJS, она совершает тяжкую ошибку. Единственное исключение, о котором я могу подумать, - это существующий плагин jQuery, который слишком сложно портировать, который изменяет ввод автоматически, и в этом случае подключение к обратному вызову или установка часов абсолютно необходимы для приведения изменений в соответствие с приложением.
Джош Дэвид Миллер

407

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

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

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

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

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

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

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

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

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

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

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

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

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


1
Можете ли вы, пожалуйста. объяснить, как элемент dom отличается от представления?
Раджкамаль Субраманян

22
@rajkamal, элемент DOM - это (очевидно) отдельный элемент, а в jQuery это часто то, что мы выбираем / нацеливаем / манипулируем. Угловое представление - это коллекция / шаблон связанных элементов DOM: представление меню, представление заголовка, представление нижнего колонтитула, представление правой боковой панели, представление профиля, может быть несколько представлений основного содержимого (переключаемых через представление ng). По сути, вы хотите разбить вашу страницу (страницы) на разные виды. Каждое представление имеет свой собственный связанный контроллер. Каждый вид проецирует часть вашей модели.
Марк Райкок

3
JQuery является НЕ императивом. onи whenявляются функциями высшего порядка, работающими с членами объекта коллекции jQuery.
Джек Вирс

18
Так какой код выполняется в обратном вызове on? Императив.
cwharris

5
Этот императив против декларативного на самом деле просто вопрос абстракций. В конце концов, весь декларативный код (что делать) обязательно (как это сделать) реализуется либо разработчиком в подпрограмме на более низком уровне абстракции, либо фреймворком, либо компилятором / интерпретатором. Сказать, что «jQuery является императивом» в общем-то, довольно странное утверждение, особенно если учесть, что на самом деле он предоставляет гораздо более декларативный API в отношении «ручной» DOM-манипуляции.
Алекс

184

AngularJS против JQuery

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

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

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

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

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

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

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

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

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

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

Давай перейдем к мельчайшим пескам.

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

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

Миско любит 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, чем на Ruby on Rails .

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

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

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

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

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

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

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

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

Разделение интересов (SOC) против MVC

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

  1. HTML - семантическое значение. HTML должен стоять отдельно.
  2. CSS - стилизация, без 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 - писать большие большие плагины, такие как лайтбокс, которые мы затем настраиваем, передавая множество значений и опций.

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

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

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

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

В AngularJS мы пишем меньшие директивы. Наша выпадающая директива была бы смехотворно мала. Он может поддерживать сложенное состояние и предоставлять методы для fold (), unfold () или 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, которая по умолчанию наследует от своей оболочки $ scope, используя прототипическое наследование JavaScript. Объект $ scope доступен в контроллере и представлении.

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

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

Это может показаться сложным, на самом деле, когда вы расслабляетесь, это похоже на полет. Вам не нужно создавать объект $ 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значение будет обновлено, шаблон тоже обновится.

Аякс все время

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

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

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

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

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

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

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

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

Инъекция зависимости (DI) и инстистация

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

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

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 и вуаля, у вас есть доступ ко всем функциям, связанным с Flickr, в вашем новом приложении.

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

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

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

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

Думайте меньше о ненавязчивом JavaScript, и вместо этого думайте с точки зрения расширений HTML.

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

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


6
Идея, что «Разделение проблем» отличается от «MVC (Модель, Представление, Контроллер)», является полностью ложной. Модель разделения интересов в веб-языках (HTML, CSS и JS) делает это, позволяя людям размещать материалы на веб-странице (разметка / HTML), не заботясь о том, как она выглядит (стиль / макет / CSS) или что она "делает" (DOM события / AJAX / JavaScript). MVC также разделяет проблемы. Каждый «слой» в шаблоне MVC играет особую роль - данные, маршрутизация / логика или рендеринг. Слои связаны обратными вызовами, маршрутами и привязками моделей. Теоретически, человек может специализироваться на каждом слое, что часто имеет место.

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

Ты прав. SOC - это широкий термин, но в веб-мире SOC имеет (или, возможно, имел) очень специфическое значение: семантический HTML, презентационный CSS и JavaScript для поведения. Я делаю некоторые предположения о своей аудитории, которые, возможно, не являются разумными, поэтому я должен также извиниться.
суперсветовой

Я считаю ваш ответ наиболее ясным и поучительным. Я здесь новичок, так что, если у меня есть расширение для изменения существующей страницы (которое я не контролирую), тогда я должен сохранить JQuery?
Даниэль Мёллер

152

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

Императив против декларативного

С помощью jQuery вы сообщаете DOM, что должно произойти, шаг за шагом. С AngularJS вы описываете, какие результаты вы хотите, но не как это сделать. Подробнее об этом здесь . Также ознакомьтесь с ответом Марка Райкока.

Как я по-разному проектирую и разрабатываю клиентские веб-приложения?

AngularJS - это целая клиентская среда, которая использует шаблон MVC (посмотрите их графическое представление ). Это сильно фокусируется на разделении интересов.

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

JQuery это библиотека

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

Основное внимание уделяется разделению задач и тестированию ( модульное тестирование и сквозное тестирование), что облегчает разработку через тестирование.

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

Существуют ли какие-либо соображения / ограничения на стороне сервера?

Вы можете использовать его в существующих приложениях, где вы уже используете чистый jQuery. Однако, если вы хотите в полной мере воспользоваться возможностями AngularJS, вы можете рассмотреть кодирование на стороне сервера с использованием подхода RESTful .

Это позволит вам использовать их фабрику ресурсов , которая создает абстракцию вашего RESTful API на стороне сервера и делает невероятно простыми вызовы на стороне сервера (получение, сохранение, удаление и т. Д.).


27
Я думаю, что вы мутите воду, говоря о том, что jQuery - это «библиотека», а Angular - это «фреймворк» ... с одной стороны, я думаю, что можно утверждать, что jQuery - это фреймворк ... это абстракция манипулирования DOM и обработки событий. Это не может быть основой для такого же рода вещи , что Угловая есть, но это дилемма , что вопрос-Аскер в: они действительно не знают разницы между угловой и JQuery, и все спрашивающий знает, JQuery является фреймворк для создания клиентских сайтов. Так что спор о терминологии не прояснит ситуацию.
Зандо

15
Я думаю, что вы тот, кто запутался. Этот вопрос относится именно к этому stackoverflow.com/questions/7062775 . Кроме того, этот ответ может помочь прояснить, в чем разница между фреймворком и библиотекой: stackoverflow.com/a/148759/620448
Ulises

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

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

84

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

AngularJS меняет способ поиска элементов

В jQuery вы обычно используете селекторы для поиска элементов, а затем подключаете их:
$('#id .class').click(doStuff);

В AngularJS вы используете директивы для прямой маркировки элементов и их соединения:
<a ng-click="doStuff()">

AngularJS не нуждается (или не хочет), чтобы вы находили элементы с помощью селекторов - основное отличие между jqLite AngularJS и полнофункциональным jQuery заключается в том, что jqLite не поддерживает селекторы .

Поэтому, когда люди говорят «вообще не включать jQuery», это происходит главным образом потому, что они не хотят, чтобы вы использовали селекторы; они хотят, чтобы вы научились использовать директивы вместо этого. Прямой, а не выбор!


13
Так же, как заявление об отказе от ответственности, между Angular и jQuery есть МНОГИЕ более существенные различия. Но поиск элементов - это то, что требует самого большого изменения мышления.
Скотт Риппи

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

3
@AlexanderPritchard Суть Angular в том, что вы выбираете не из своего JavaScript, а прямо из шаблона. Это инверсия контроля, которая передает власть в руки дизайнера. Это продуманный принцип проектирования. Чтобы действительно получить Angular, вы должны думать о своем коде таким образом. Это трудный сдвиг.
суперсветовой

3
@superluminary Какая отличная цитата! "не выбирай; прямой!" Серьезно, я собираюсь использовать это.
Скотт Риппи,

1
Это одна из моих любимых вещей в AngularJS. Мне не нужно беспокоиться о том, что команда UX нарушит мою функциональность или что я нарушу их стили. Они используют классы, я использую директивы, точка. Я не скучаю по селекторам.
adam0101

69

JQuery

jQuery делает невероятно длинные команды JavaScript, такие как getElementByHerpDerpкороткие и кросс-браузерные.

AngularJS

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

Редактировать:

Говоря: «У меня есть опыт работы с jQuery, как я думаю в AngularJS?» это как сказать: «У меня есть фон HTML, как я думаю в JavaScript?» Тот факт, что вы задаете вопрос, показывает, что вы, скорее всего, не понимаете основных целей этих двух ресурсов. Вот почему я решил ответить на вопрос, просто указав на принципиальное отличие, а не просматривая список, говорящий: «AngularJS использует директивы, тогда как jQuery использует CSS-селекторы для создания объекта jQuery, который выполняет то и это и т. Д.…» , Этот вопрос не требует длинного ответа.

jQuery - это способ облегчить программирование JavaScript в браузере. Короче, кросс-браузерные команды и т. Д.

AngularJS расширяет HTML, так что вам не нужно разбираться во <div>всем, чтобы создать приложение. Это заставляет HTML фактически работать для приложений, а не для чего он был разработан, то есть для статических образовательных веб-страниц. Это делается окольным путем с использованием JavaScript, но по сути это расширение HTML, а не JavaScript.


@ Роберт зависит от того, что ты делаешь. $(".myclass")это чрезвычайно распространено, и более чем немного проще в jQuery, чем PO-Javascript.
Роб Грант

61

jQuery: вы много думаете о том, чтобы «ЗАПРОСИТЬ DOM » для элементов DOM и что-то делать.

AngularJS: модель - это правда, и вы всегда думаете об этом УГОЛЕ.

Например, когда вы получаете данные с сервера THE, которые вы намереваетесь отобразить в каком-либо формате в DOM, в jQuery, вам необходимо '1. НАЙТИ 'где в DOM вы хотите разместить эти данные' 2. UPDATE / APPEND 'это там, создав новый узел или просто установив его innerHTML . Затем, когда вы хотите обновить это представление, вы затем '3. НАЙТИ 'местоположение и' 4. ОБНОВИТЬ'. Этот цикл поиска и обновления, выполненный в одном контексте получения и форматирования данных с сервера, исчез в AngularJS.

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

Говоря по - другому, в JQuery, вы должны думать о CSS селекторов, то есть, где находится divили tdчто имеет класс или атрибут, и т.д., так что я могу получить свой HTML или цвет или значение, но в AngularJS, вы поймете, что думаете так: с какой моделью я имею дело, я установлю значение модели на true. Вы не беспокоитесь о том, является ли представление, отражающее это значение, установленным флажком или находится в tdэлементе (подробности, о которых вам часто приходилось бы думать в jQuery).

А с манипулированием DOM в AngularJS вы обнаруживаете, что добавляете директивы и фильтры, которые вы можете рассматривать как допустимые расширения HTML.

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


46

Это очень хорошие, но длинные ответы.

Подводя итог моему опыту:

  1. Контроллеры и провайдеры (сервисы, фабрики и т. Д.) Предназначены для изменения модели данных, а не HTML.
  2. HTML и директивы определяют макет и привязку к модели.
  3. Если вам нужно обмениваться данными между контроллерами, создайте сервис или фабрику - они являются единичными элементами, которые совместно используются приложением.
  4. Если вам нужен виджет HTML, создайте директиву.
  5. Если у вас есть данные и вы пытаетесь обновить HTML ... STOP! обновите модель и убедитесь, что ваш HTML привязан к модели.

45

jQuery - это библиотека манипулирования DOM.

AngularJS - это фреймворк MV *.

На самом деле AngularJS является одной из немногих платформ JavaScript MV * (многие инструменты JavaScript MVC все еще попадают в библиотеку категорий).

Будучи фреймворком, он содержит ваш код и принимает решения о том, что и когда вызывать!

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

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

AngularJS включает в себя некоторую кривую обучения (больше, чем jQuery :-).

-> Для любого разработчика, пришедшего из jQuery, мой первый совет: «Изучите JavaScript как язык первого класса, прежде чем переходить к богатой среде, такой как AngularJS!» Я узнал вышеупомянутый факт трудным путем.

Удачи.


34

Это яблоки и апельсины. Вы не хотите сравнивать их. Это две разные вещи. AngularJs уже имеет встроенный jQuery lite, который позволяет вам выполнять базовые манипуляции с DOM, даже не включая полнофункциональную версию jQuery.

JQuery это все о манипуляции с DOM. Он решает все проблемы между браузерами, в противном случае вам придется иметь дело с этим, но это не платформа, которая позволяет разделить ваше приложение на такие компоненты, как AngularJS.

Хорошая особенность AngularJs заключается в том, что она позволяет вам отделять / изолировать манипуляции с DOM в директивах. Есть готовые к использованию встроенные директивы, такие как ng-click. Вы можете создавать свои собственные пользовательские директивы, которые будут содержать всю вашу логику представления или манипулирование DOM, чтобы вы не в конечном итоге смешали код манипуляции DOM в контроллерах или сервисах, которые должны заботиться о бизнес-логике.

Angular разбивает ваше приложение на - Контроллеры - Сервисы - Представления - и т. Д.

и есть еще одна вещь, это директива. Это атрибут, который вы можете прикрепить к любому элементу DOM, и вы можете сходить с ума с jQuery, не беспокоясь о том, что ваш jQuery когда-либо конфликтует с компонентами AngularJs или портится с его архитектурой.

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


31

Слушайте подкаст JavaScript Jabber: Эпизод # 32 котором представлены оригинальные создатели AngularJS: Misko Hevery и Igor Minar. Они много говорят о том, что значит приходить в AngularJS из других фонов JavaScript, особенно из jQuery.

Один из моментов, сделанных в подкасте, заставил меня задуматься о вашем вопросе:

MISKO : [...] одна из вещей, о которых мы очень редко думали в Angular, это то, как мы предоставляем много аварийных люков, чтобы вы могли выбраться и найти выход из этого. Поэтому для нас ответом является то, что называется «Директивы». А с помощью директив вы по сути становитесь обычным маленьким jQuery JavaScript, вы можете делать все, что захотите.

ИГОРЬ : Итак, воспринимайте директиву как инструкцию для компилятора, которая сообщает ее всякий раз, когда вы сталкиваетесь с этим определенным элементом или этим CSS в шаблоне, и вы сохраняете этот вид кода, и этот код отвечает за элемент и все, что находится под этим элементом в дереве DOM.

Стенограмма всего эпизода доступна по ссылке, указанной выше.

Итак, чтобы прямо ответить на ваш вопрос: AngularJS очень-очень самоуверен и является истинной средой MV *. Тем не менее, вы можете делать все действительно крутые вещи, которые вы знаете и любите, с помощью jQuery в директивах. Это не вопрос "Как мне делать то, что я делал в jQuery?" вопрос "Как я могу дополнить AngularJS всем, что я делал в jQuery?"

Это действительно два совершенно разных состояния ума.


2
Я не уверен, что согласился бы с тем, что Angular ОЧЕНЬ самоуверен. Хочешь самоуверенного, посмотри на Эмбер. Я бы изобразил в Angular мнения о златовласке - во многих случаях я вижу, что у jQuery слишком мало мнений, а у Ember слишком много. Angular, кажется, просто прав.
fool4jesus

30

Я нахожу этот вопрос интересным, потому что моим первым серьезным знакомством с программированием на JavaScript были Node.js и AngularJS. Я никогда не изучал jQuery, и я думаю, что это хорошо, потому что мне не нужно ничего учить. На самом деле, я активно избегаю решения своих проблем с помощью jQuery и вместо этого ищу исключительно «AngularJS-способ» для их решения. Итак, я думаю, что мой ответ на этот вопрос, по сути, сводится к «думать как кто-то, кто никогда не изучал jQuery» и избегать любого соблазна включить jQuery напрямую (очевидно, AngularJS использует его в некоторой степени за кулисами).


23

AngularJS и JQuery:

AngularJs и JQuery совершенно разные на всех уровнях, кроме функциональности JQLite, и вы увидите это, как только начнете изучать основные функции AngularJs (я объяснил это ниже).

AngularJs - это клиентская среда, которая предлагает создать независимое клиентское приложение. JQuery - это клиентская библиотека, которая работает с DOM.

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

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

Двухстороннее связывание данных удивительно: у меня была сетка со всеми функциями UPDATE, DELTE, INSERT. У меня есть объект данных, который связывает модель сетки с помощью ng-repeat. Вам нужно всего лишь написать одну строку простого кода JavaScript для удаления и вставки, и все. Сетка автоматически обновляется при мгновенном изменении модели сетки. Обновление функционирует в режиме реального времени, для него нет кода. Вы чувствуете себя потрясающе !!!

Директивы многократного использования - это супер: пишите директивы в одном месте и используйте их во всем приложении. О, МОЙ БОГ!!! Я использовал эти директивы для подкачки страниц, регулярных выражений, проверок и т. Д. Это действительно круто!

Маршрутизация сильна: ваша реализация зависит от того, как вы хотите ее использовать, но для маршрутизации запроса на указание HTML и контроллера требуется очень мало строк кода (JavaScript)

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

Плагины: есть много других похожих функций, таких как отображение наложения в вашем приложении. Вам не нужно писать код для него, просто используйте плагин наложения, доступный как wc-overlay, и он автоматически позаботится обо всех запросах XMLHttpRequest (XHR).

Идеально подходит для архитектуры RESTful : будучи полным фреймворком, AngularJS отлично подходит для работы с архитектурой RESTful. Вызвать API REST CRUD очень просто и

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

Расширяемость : Angular расширил директивы HTML с помощью угловых директив. Напишите выражения внутри html и оцените их во время выполнения. Создайте свои собственные директивы и сервисы и используйте их в другом проекте без каких-либо дополнительных усилий.


20

Будучи новичком в JavaScript MV * и сосредоточенным исключительно на архитектуре приложения (не на стороне сервера / клиента), я бы, конечно, порекомендовал следующий ресурс (который, я удивлен, еще не упоминался): шаблоны проектирования JavaScript , автор Addy Osmani , как введение в различные шаблоны проектирования JavaScript . Термины, используемые в этом ответе, взяты из связанного документа выше. Я не собираюсь повторять то, что было действительно хорошо сформулировано в принятом ответе. Вместо этого этот ответ связан с теоретическими основами, на которых основан AngularJS (и другие библиотеки).

Как и я, вы быстро поймете, что AngularJS (или Ember.js , Durandal и другие MV * фреймворки в этом отношении) - это одна сложная фреймворк, объединяющая множество различных шаблонов проектирования JavaScript.

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

Например:

  • JavaScript Объектно-ориентированное программирование (это поисковая ссылка Google). Это не библиотека, но, безусловно, обязательное условие для любого прикладного программирования. Он научил меня нативным реализациям прототипа, конструктора, шаблонов синглтона и декоратора
  • JQuery / Underscore для шаблона фасада (как WYSIWYG для управления DOM)
  • Prototype.js для шаблона прототип / конструктор / миксин
  • RequireJS / Curl.js для шаблона модуля / AMD
  • KnockoutJS для наблюдаемого шаблона публикации / подписки

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


12

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

Я обычно разрабатываю мобильные приложения, используя AngularJS и Cordova . ЕДИНСТВЕННАЯ вещь от jQuery, в которой я нуждался, является Селектором.

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

И я решил сделать крошечный фрагмент кода, который поможет мне быстро запустить сайт, используя AngularJS с мощью jQuery Selector (используя Sizzle).

Я поделился своим кодом здесь: https://github.com/huytd/Sizzular

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.