От «сделай то» к «пусть будет так»: как перестать писать jQuery и начать мыслить AngularJS
Если вы пришли в мир AngularJS из jQuery, вы, скорее всего, испытываете культурный шок. В jQuery вы привыкли командовать: «Найди этот элемент, измени ему класс, добавь туда текст». В AngularJS всё иначе. Вы говорите: «Вот данные. Пусть шаблон сам за ними следит». Это не просто смена библиотеки — это смена парадигмы.
В 2025 году AngularJS (версии 1.x) всё ещё жив в legacy-проектах, и понимание его философии — ключ к успешной работе. Если вы пытаетесь писать AngularJS как jQuery, вы обречены на боль и баги. Давайте разберёмся, как переключить мозг.
Проблема №1: Вы всё ещё манипулируете DOM
В jQuery вы пишете:
// jQuery style
$('#myButton').click(function() {
$('#myDiv').text('Нажато!').addClass('active');
});
В AngularJS так делать нельзя. DOM — это просто отражение состояния. Вместо того чтобы трогать DOM напрямую, вы меняете модель (данные), и Angular сам обновляет представление.
// AngularJS style
angular.module('app', [])
.controller('MainCtrl', function($scope) {
$scope.buttonText = 'Нажми меня';
$scope.isActive = false;
$scope.handleClick = function() {
$scope.buttonText = 'Нажато!';
$scope.isActive = true;
};
});
А в HTML:
<div ng-app="app" ng-controller="MainCtrl">
<button ng-click="handleClick()">{{ buttonText }}</button>
<div ng-class="{active: isActive}">{{ buttonText }}</div>
</div>
Заметили? Ни одного селектора, ни одного прямого обращения к DOM. Всё управляется через $scope и директивы.
Проблема №2: Вы пишете утилитарные функции вместо сервисов
В jQuery вы часто создаёте набор глобальных функций:
// jQuery style (плохо)
function getUser(id) {
return $.get('/api/users/' + id);
}
function showError(msg) {
$('#error').text(msg).show();
}
В AngularJS вы должны использовать сервисы — синглтоны, которые инжектируются туда, где нужны. Это даёт тестируемость, переиспользование и чистоту кода.
// AngularJS style (хорошо)
angular.module('app')
.factory('UserService', function($http) {
return {
getUser: function(id) {
return $http.get('/api/users/' + id);
}
};
})
.controller('ProfileCtrl', function($scope, UserService) {
UserService.getUser(1).then(function(response) {
$scope.user = response.data;
});
});
Забудьте про глобальные переменные и функции. Всё должно жить внутри модулей Angular.
Проблема №3: Вы используете $(document).ready()
В jQuery вы ждёте загрузки DOM:
$(document).ready(function() {
// ваш код
});
В AngularJS это не нужно. Контроллеры и директивы инициализируются автоматически, когда Angular "компилирует" DOM. Вместо ready() используйте $scope.$on('$viewContentLoaded', ...) или просто поместите логику инициализации в конструктор контроллера.
angular.module('app')
.controller('StartupCtrl', function($scope) {
// Этот код выполнится, когда контроллер будет создан
$scope.init = function() {
console.log('Контроллер готов!');
};
$scope.init();
});
Проблема №4: Вы пишете «спагетти-код» с колбэками
jQuery поощряет цепочки колбэков и вложенные вызовы. AngularJS предлагает промисы ($q) и чистую архитектуру.
// jQuery style (ад колбэков)
$.get('/data', function(data) {
$.post('/save', data, function(result) {
$.get('/status', function(status) {
// ...
});
});
});
// AngularJS style (промисы)
UserService.getUser(1)
.then(function(user) {
return OrderService.getOrders(user.id);
})
.then(function(orders) {
$scope.orders = orders;
})
.catch(function(error) {
$scope.error = 'Ошибка загрузки';
});
Проблема №5: Вы не используете двустороннее связывание
Это главная фишка AngularJS. В jQuery вы вручную синхронизируете данные и DOM:
// jQuery style
$('#input').on('keyup', function() {
$('#preview').text(this.value);
});
В AngularJS это делается автоматически с помощью ng-model:
<input ng-model="user.name">
<p>Привет, {{ user.name }}!</p>
Всё. Никаких обработчиков событий, никаких ручных обновлений. Данные и представление всегда синхронизированы.
Лучшие практики AngularJS в 2025 году
Даже если вы работаете с AngularJS 1.x, вот что стоит делать, чтобы код был современным и поддерживаемым:
- Используйте компонентный подход — вместо контроллеров с
$scopeпереходите на.component()(доступен с версии 1.5). Это подготовит вас к Angular 2+. - Избегайте $scope.$apply() — если вы чувствуете, что нужно вызвать
$apply, значит, вы что-то делаете не так. Используйте сервисы Angular ($http, $timeout) вместо нативных API. - Держите контроллеры «тощими» — вся бизнес-логика должна быть в сервисах. Контроллер только связывает данные с шаблоном.
- Пишите директивы для переиспользования — если вы повторяете один и тот же HTML с логикой, вынесите это в директиву.
- Тестируйте — используйте Jasmine и Karma. AngularJS спроектирован для тестирования, не упускайте это преимущество.
Пример: переписываем jQuery-плагин на AngularJS
Допустим, у вас есть jQuery-плагин для выпадающего списка:
// jQuery plugin
$.fn.myDropdown = function(options) {
return this.each(function() {
var $this = $(this);
$this.on('click', function() {
$this.find('.menu').toggle();
});
});
};
// Использование
$('.dropdown').myDropdown({ animation: 'slide' });
В AngularJS это превращается в директиву:
angular.module('app')
.directive('myDropdown', function() {
return {
restrict: 'A',
scope: {
animation: '@'
},
link: function(scope, element) {
element.on('click', function() {
var menu = element.find('.menu');
if (scope.animation === 'slide') {
menu