去年 IE Team 把 issue tracker 放到 StackOverflow 之后,我一度以为 SO 会革了 MSDN Library 和 Forum 的命(也就是让我丢掉饭碗),就像 GitHub 干掉 Codeplex 和 Google Code 一样。刚好当时我学习和实践 AngularJS 有一段时间了,我就想到 SO 上试试身手,看看自己的水平,是否能够帮助到别人。
于是我每天大概花半个小时不到在 SO 的 Angular JS tag 下面解答问题。玩了半个月左右,拿到一千多分。在 SO 上刷分当然不是目的,但是分数比较好的体现了你回答的问题的准确度和热门度,所以我比较关注这个指标,但这个过程只能用艰难来形容。之所以称之为艰难,主要原因有两个。
这两个现象其实都来源于一个 root cause :基础的问题,回答起来更容易,花的时间更少,得到的分数更多。而这样的问题,受到所有人的喜爱。为什么呢?对于抢分狂魔而言,这种题目分数更好得;对于热心答题不计较分数的好心人而言,回答这种问题,能够把时间省下来帮助更多的人,何乐而不为?当整个社区都呈现这种状态是,你就不难得到当年老赵对 SO 的评论: 如果你经过深思熟虑也无法解决的问题,丢到 SO 上,也基本上不会得到你想要的答案
。这是个悲伤的结论,但 it’s true 。
SO 其实也意识到这个问题了我估计,于是他们搞了个 Golden Badge 叫做 Unsung Hero
。获得这个 Badge 的条件是,你超过一半的答案被选为正确答案,但是没人给你 upvote(也就意味着关注度小)。真的是名副其实,无名英雄。最开始拿到这个 Badge 的时候,我并没有特别高兴。但当我得到上面的结论时,我就释然了。高兴了无聊了工作累了,我就爬上去回答一些我知道的问题。
这几天突然看到自己又一次上了 AngularJS 这个 Tag 的 Last 30 days top answerers
,我想,既然在 SO 上最热门最抢手的问题都是比较基础的、简单的,这也间接说明,对于新手而言,这些知识点具备一定学习曲线,并没有那么容易上手和熟悉。如果把这些知识点和问题做一个整理,这一定是一个不错的文档,也能从中看出这个语言或框架在设计方面的不足。于是我从前到后阅读了一遍我回答过的 Angular 的问题,很快发现不少反复出现或者同类型的提问。
下面让我们一起,从我的角度,看看大家学习 Angular 1.x 的时候通常会遇到哪些困难。
第一类问题是关于 Angular 的运行原理。像 ASP.NET 这种框架,你大部分时候都不需要理解它的机制,而当你不得不去理解 ASP.NET 是怎么运行,那基本说明你遇到了非常坑爹的问题了。但是 Angular 并不是这样的,即使你是上手才半个礼拜的新手,当你需要完成一些特定的功能,你就不得不理解 Angular 的 principles,否则你就会掉入坑中爬不出来。这也就是业界对 Angular 最大的批评,学习曲线比较高。
这是我心目中的 Angular 第一大杀手。很多前端工程师从纯 JS 或者别的框架迁移到 Angular 的时候,最经常问的就是,为什么我更新了某某 object 的值,页面上没有更新呢? Angular 使用 Digest cycle 来实现 two way binding,而他们的操作并没有进入到这个 cycle 中,比如 ace update text , show json , image change 。 GitHub 上有这样一群 repo ,他们专门负责把第三方的 library 进行包装,使得能够在 Angular 中使用。老实讲, Angular 养活了一批人呢。等2.0上市了,大家又要一股脑儿把这些 library 重新包装,有兴趣的同学不妨试试,是个不错的学习 Angular 和 Contribute to Open Source 的机会。
还有就是在写 directive 的时候,更新了 model 却不能 刷新 页面
好不容易 developer 知道可以使用 $apply
$digest
去手动 trigger digest loop,他们也会经常遇到 infinite digest cycle 的问题,简直要疯了。
Angular 中有你可以这么使用expression
<input type="text" name="userName" ng-model="user.name"
<p>My first expression: {{ value }}</p>
。 可是奇怪的事情,当你使用 ng-src
的时候,你需要这样写 <img ng-src="http://www.gravatar.com/avatar/{{hash}}" alt="Description"/>
… 我已经不知道该说什么好了 …你可以再看看这里 1 , 2 。
很多人搞不对expression也可能是因为没有理解 scope 。scope 既是连接 controller 和 view 的胶水,也是 expression 的运行环境。很多朋友在这里栽了,带来的结果往往是搞不定 data binding 。
如果你只是通过官方的demo来学习Angular,你可能会搞不清楚 angular.module('app', [])
和 angular.module('app')
的区别,并且由于调用的错误,导致 module 不断地被反复 initialize 。
在 module 的 bootstrap 过程中,你可以通过指定自定义的 Configuration blocks 来操作 provider/constants,或者使用 Run blocks 来配置 instances/constants ,千万不要 错用了 。
一般 dependency injection 出现问题,基本都是用户粗心 漏掉了某个 factory ,或者是使用了 minification 。
什么是 directive ,这里我只简单贴一下官方的说法
At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.
directive 能够很好滴帮助实现模块化,在 Angular 在自己的实现过程中,就把不少功能以 directive 的方式提供给开发者。用户也可以自己书写 directive 对功能进行抽象。在我看来,directive 往往是初学者比较难以掌握的。
首先是 Angular 提供的 directive 。有的时候,即使是认真研习文档,你也不一定能够成功理解它们的运行机制,很多朋友在这里就吃了苦头了。印象里 built-in directive 这个方面我拿分相对容易,因为我比较勤劳,如果文档不能够帮助解决问题的话,我会直接跑去看源码。如果问我泡 StackOverflow 最大的收获是什么,那一定是读了不少 Angular 的 source code。
SO 上经常会提及的 built-in directive 有
除了使用 built-in 的 directive ,Angular 也鼓励大家来写自己的 directive。但是这里大家经常会遇到 model binding 或者是如何给 attr 传值 ,再或者从 directive 中 访问 controller 的 scope 。
$http 只是一个 built-in 的 service ,但我要把它单独拿出来讲一讲,一方面是因为这是一个非常基础的 service (访问后台 Rest API ),另一方面是 developer 在和 $http 总会不约而同的想静静。
最后,读者朋友如何跑到我博客首页看一看,你还能看到去年我对 Angular 的吐槽 Angular 一个值得当心的bug 。是的,我喷的就是 $http ,虽然没有什么卵用。
还有一类问题,来自有理想有追求的朋友。他们想知道如何 think in Angular,如何操作能够有比较好的 performance等等。
当你想在不同的 context 之间共享 data 的时候,全局变量堪称 fast and dirty 。但不幸的是,从你上大学的第一天开始,就有人不断告诉你这么做是不负责任滴。于是为了避免被同事 code review 的时候 challenge,不断有人来问该 如何 在 controller/factory/directive/etc 之间 share data 。俗称,月经帖。
其实这个和上文提到的digest loop可以放在一起谈。Angular 使用了 dirty check 去实现 two-way binding,也就是很傻瓜地反复地遍历 watch list,看看大家有没有什么更新。当页面上的绑定的 element 开始增多(大概2000+),dirty check 就会严重拖累整个页面的 performance。
dirty check 简直是 Angular 1.x 的阿克琉斯之踵,然后谷歌的大大们在2.0中,把它无情地抛下了。听闻这个消息,我等屁民“弹冠相庆”,谁让它 老是 折磨 我们 呢。
去年四月我第一次接触 Angular,写了点自嗨的小玩具,转眼已经过去十三月了。短短的一年光阴,Angular 1.x 已经确立了不可撼动的一哥地位,而2.0 也已经“洗心革面”马上要出来重新做人。至于我,在尝试完各种姿势之后,也算是找到了一点方向。希望2015年剩下的时间里,做好一个产品,来一点 breaking change。
Breaking Change!! Hell Yeah!!