日期:2014-05-16  浏览次数:20355 次

Think in AngularJS:对比jQuery和AngularJS的不同思维模式

?

Think in AngularJS:对比jQuery和AngularJS的不同思维模式

?

大漠穷秋

?

导言

?

stackoverflow上有一个人问了一个问题:如果我有jQuery背景,我应该如何切换到AngularJS的思维模式?

?

有一个回复非常经典,获得了两千多票。

?

为了让国内开发者也能领略到其中的核心思想,现把这个问题和答案翻译出来供大家参考。

?

Question

?

假设我已经熟悉了如何使用jQuery来开发客户端应用,我现在打算使用AngularJS。请描述一下有那些思维模式方面的东西需要转变吗?下面是举出一些具体的问题,用来帮助你回答我的这个问题:

?

  1. 我应该以何种不同的方式来架构和设计客户端web应用?最大的不同点是什么?
  2. 我应该停止使用哪些东西;又应该开始使用哪些东西来替代?
  3. 服务端有没有什么需要考虑或者说需要约束的地方?

?

PS:我不想详细对比jQuery和AngularJS之间的不同点。

?

Answer

?

1.不要预先设计页面,然后再用DOM操作去修改它

?

在jQuery里面,你会先设计好一个页面,然后再让它变成动态的。这是因为jQuery本身就是以混合使用的思路来设计的。基于这个简单的前提,jQuery目前已经变得臃肿不堪。

?

但是在AngularJS的世界中,你心中首先必须有整体架构,然后从零开始构建应用。而不是一开始的时候就去想:“我已经有了这样一块DOM结构,我想让它做×××”,你必须首先思考你到底要完成什么功能,然后再开始动手,然后再设计你的应用,最后再去设计你的视图。

?

2.不要混合使用jQuery和AngularJS

?

类似地,不要一开始就抱有这样的想法:jQuery可以实现X、Y和Z,所以我只要在上面再覆盖一层AngularJS,把模型和控制器加上即可。当你刚开始使用AngularJS的时候,这种想法实在诱人,这也是为什么我总是建议AngularJS新手彻底抛弃jQuery的原因,直到他们习惯了以“Angular风格”去做事为止。

?

在这里,以及在邮件列表里面,我看到过很多这种精心设计的解决方案,其中包含150或者200行代码的jQuery插件,然后他们再用一大堆回调函 数和$apply把这些插件粘到AngularJS上,这种做法非常复杂而且令人困惑不已;但是,他们最终居然能把这货弄跑起来了!这里的问题在于,在大 多数情况下,只需要很少的AngularJS代码就可以把这些jQuery插件重写一遍,然后所有事情都会突然变得简洁明了起来。

?

底线是:在解决问题的过程中,首先“Think in AngularJS”(以AnguarJS的方式思考问题);如果你想不到解决方案,请求助于社区;如果在尝试了所有这些方法之后还找不到简单的解决方案,然后再求助于jQuery。但是,不要让jQuery变成绊脚石,否则你永远无法真正掌握AngularJS。

?

3.保持以架构的角度思考

?

首先要明确一点,单页面应用是一种应用,它们不是web页面。所以,我们需要像服务端开发者那样去思考,而不是像客户端开发者那样思考。我们必须思考如何把我们的应用切分成独立的、可扩展的、可测试的组件。

?

那么,你怎么才能做到这一点呢?你应该如何以AngularJS的方式思考问题呢?下面是一些基本的原则,与jQuery做个对比。

?

假设有一个叫做“官方记录”(official record)的视图

?

在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新手经常会问这样的问题:我怎么才能找出某种类型的所有超链接,然后在上面加上指令呢?我们会这样回答他:你不应该这么做。然后 他总是一副惊呆了样子。你不应该这么做的原因是:这是一种半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>

?

这种方式除了会把注意点混在一起之外,还有我在前面所提到的思维模式问题。但是,更加重要的一点是,这样做我们必