从jQuery背景出发思考AngularJS编程思维

从jQuery背景出发思考AngularJS编程思维

技术背景

jQuery是一个广泛使用的JavaScript库,主要用于简化DOM操作、处理事件和执行动画等。它以命令式编程为主,通过选择器查找DOM元素并进行操作。而AngularJS是一个功能强大的前端框架,采用声明式编程,使用MVC(Model-View-Controller)或MVVM(Model-View-ViewModel)架构,强调数据绑定、模块化和可测试性。对于有jQuery背景的开发者来说,需要进行编程思维的转变才能更好地使用AngularJS。

实现步骤

架构设计优先

在jQuery中,通常先设计页面,再通过DOM操作使其动态化。而在AngularJS中,要从架构层面出发,先明确要实现的功能,再设计应用,最后设计视图。例如,在设计一个菜单时,不要先考虑如何对现有的DOM元素进行操作,而是先规划好菜单的功能和数据结构,再用AngularJS的指令和数据绑定来实现。

避免用AngularJS扩展jQuery

不要一开始就想着在jQuery的基础上添加AngularJS来实现模型和控制器。建议新的AngularJS开发者至少在熟悉“Angular方式”之前不要使用jQuery。当遇到问题时,先尝试用AngularJS的方式解决,如果实在没有办法,再考虑使用jQuery。

以架构的思维思考

视图即“官方记录”

在jQuery中,通过编程方式改变视图,从视图上很难直接看出其功能。而在AngularJS中,视图包含了基于视图的功能信息,通过指令明确告诉开发者视图的作用。例如,使用dropdown-menu指令来激活下拉菜单,新的开发人员可以直接从模板中了解到该元素有下拉菜单的功能。

数据绑定

AngularJS的数据绑定功能可以自动更新视图,减少了DOM操作的需求。在jQuery中,需要手动响应事件并更新内容,而在AngularJS中,只需要更新模型,视图会自动更新。例如,通过$http获取数据后,将数据添加到$scope中,视图会自动显示新的数据。

独立的模型层

与jQuery中DOM类似模型不同,AngularJS有独立的模型层,可以独立于视图进行管理,这有助于数据绑定、关注点分离和提高可测试性。

关注点分离

AngularJS通过视图、模型、服务层、指令和控制器等组件来实现关注点分离。视图作为功能的记录,模型表示数据,服务层执行可复用的任务,指令进行DOM操作和增强视图,控制器将它们连接在一起。

依赖注入

依赖注入(DI)有助于实现关注点分离。在AngularJS中,可以自由声明组件,并在其他组件中请求实例,而不需要关心加载顺序和文件位置。例如,在测试控制器时,可以使用模拟服务来替代真实的服务。

始终采用测试驱动开发

AngularJS适合进行测试驱动开发。与jQuery不同,在AngularJS中可以先编写测试用例,然后实现相应的功能。例如,在创建一个指示当前路由的指令时,可以先编写测试用例,确认测试失败后再实现指令,最后确保测试通过。

理解指令不是封装的jQuery

指令是HTML的扩展,用于实现自定义的HTML元素和属性。在使用指令时,要尽量避免使用jQuery进行DOM操作,而是使用AngularJS提供的工具,如ngClassngModel等。例如,实现一个可切换的按钮,应该使用ng-classng-click来实现,而不是使用jQuery的toggleClass方法。

核心代码

数据绑定示例

1
2
3
4
5
6
7
8
9
10
11
12
// jQuery实现
$.ajax({
url: '/myEndpoint.json',
success: function ( data, status ) {
$('ul#log').append('<li>Data Received!</li>');
}
});

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

指令示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 错误的使用jQuery的指令示例
.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);
});
}
};
});

// 正确的AngularJS指令示例
.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;
};
}
};
});

测试驱动开发示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 测试用例
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' );
}
});
}
};
});

最佳实践

  • 尽量避免在AngularJS应用中使用jQuery,除非必要。
  • 遵循关注点分离原则,将不同的功能模块分离到不同的组件中。
  • 充分利用AngularJS的数据绑定和指令功能,减少手动DOM操作。
  • 采用测试驱动开发,提高代码的可维护性和可测试性。
  • 学习JavaScript的原型继承,避免在AngularJS开发中出现常见的陷阱。

常见问题

如何处理SEO和可访问性问题

由于AngularJS将HTML作为模板,其源文件可能不具有语义性。可以使用pushstate URLs和编写良好的站点地图,同时,大多数屏幕阅读器现在可以解析JavaScript,搜索引擎也可以索引AJAX内容。

如何在AngularJS中进行DOM操作

在AngularJS中,尽量使用数据绑定和指令来实现功能,避免直接进行DOM操作。如果必须进行DOM操作,应该在指令中进行。

如何在AngularJS中共享数据

可以使用服务或工厂来共享数据,它们是单例对象,可以在整个应用中共享。


从jQuery背景出发思考AngularJS编程思维
https://119291.xyz/posts/2025-05-09.thinking-in-angularjs-with-jquery-background/
作者
ww
发布于
2025年5月9日
许可协议