angular在2009年诞生,孤陋寡闻的我在去年年底才知道有这么个东西。一开始接触的时候觉得好神奇,好酷炫,什么双向绑定的,所以就开始了解并开始试着做一些应用,用着用着就发现了angular的一些麻烦之处。每一样东西都是两面性的,所以要求十全十美是不可能的。接下来先说一说angular吸引人的地方吧:
angular是一个MVVM框架,双向绑定是其最显著的特点之一。用法非常简单:
<!DOCTYPE html><html> <body ng-app = ‘myApp‘> <input type = "text" ng-model = "data"> <div ng-controller = ‘mainCtrl‘> {{data}} </div> </body></html>
angular.module(‘myApp‘,[]) .controller(‘mainCtrl‘,function($scope){ $scope.data = ‘hello angular‘; })
angular使用双大括号‘{{}}’进行数据绑定,ng-model属性把输入框的值绑定到data变量,当输入框的值改变时div里面的值也会相应改变。
angular封装了很多它自己的属性,都是以ng开头的,有:ng-repeat,ng-change,ng-click等等,这里就以ng-repeat举例说一说,因为我一开始就是被这个属性吸引的,因为太方便了。
<!DOCTYPE html> <html> <body ng-app = ‘myApp‘> <ul ng-controller = ‘mainCtrl‘> <li ng-repeat = "list in lists"> {{list}} </li> </body> </html>
angular.module(‘myApp‘,[]) .controller(‘mainCtrl‘,function($scope){ $scope.data =[1,2,3,4,5]; })
只需要写这么简单的代码然后angular就会自动帮你遍历data这个数组,然后自己生成相应的li。效果就相当于下面的代码:
<!DOCTYPE html> <html> <body ng-app = ‘myApp‘> <ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </body> </html>
因此当你需要把相当大的数据渲染到页面的时候就显示出ng-repeat的方便了,只要很简单的几行代码。而且因为双向绑定的原因,数据源一旦发生改变,页面的数据也会跟着改变。是不是相当酷炫呢。
angular还有很多已经封装好的过滤器filter,让你能够很迅速的过滤数据,而且它还允许你自定义过滤器,自定义好像已经是现在的大趋势了,好像web component这些也是提倡自定义组件,这里就不多扯,有兴趣可以去了解一下。
<!DOCTYPE html> <html> <body ng-app = ‘myApp‘> <ul ng-controller = ‘mainCtrl‘> <li>{{data | date:‘yy-MM-dd‘}}</li> <li>{{num | currency:‘¥‘}}</li> <li>{{list | filter: ‘a‘}}</li> </ul> </body> </html>
angular.module(‘myApp‘,[]) .controller(‘mainCtrl‘,function($scope){ $scope.data =new Date().getTime(); $scope.num = 123; $scope.list = [‘abc‘,‘dds‘,‘fsdfs‘]; })
上面的例子说了比较常用的三种filter
第一种:日期过滤器,当我们处理日期的时候经常要过滤各种格式,年月日怎么显示啊,或者只显示年月,只显示月日之类的,各种日期格式都有的。
第二种:货币转换,能根据你所需要的货币类型转换
第三种:根据关键字过滤,例如上面例子的filter就是过滤list数组,把含有‘a’字母的项过滤出来,这个能够用来做搜索功能,自己研究一下呗。
对过滤器还不是很了解的话可以去看看官方文档。
angular不推荐开发者在controller里面操作dom,那么我们应该在哪里操作dom呢,就是directive里面,angular的directive就是让你自定义元素,属性,类,还是先看看例子吧。
<!DOCTYPE html> <html> <body ng-app = ‘myApp‘> <div custom-attr> test </div> </body> </html>
angular.module(‘myApp‘,[]) .directive(‘customAtrr‘,function(){ return { restrict: ‘A‘, link: function (scope, element) { element.on(‘click‘,function(){ alert(‘hello directive‘); }) } })
当你使用angular用作你的开发框架,那么你就要很小心的操作dom了,因为在angular需要在特定的地方操作dom才是最安全的,当然你在任何一个地方操作也是可以的,可是这样就有可能会发生一些你自己也不知道怎么出现的问题(我也不知道。。。),所以最好还是按照规范来写。在上面的例子当中,定义一个directive,里面的link函数就是能够操作dom的其中一个地方,还有compile函数,就是说所有涉及dom的操作最好都是在这些函数当中完成,angular官方的解释就是说在这些函数当中操作dom是最安全的。directive里面的‘restrict‘属性有四个值可选,E、C、M、A;
E:只能用作元素的,就像div这种
C:只能用作类,样式类,class
M:只能用作注释
A:只能用作属性,attribute,如id这种
当然你可以几个一起用,看你具体需要。
这里我只是谈了angular入门应该了解的几个功能,angular还有很多其他功能,这里我就不详谈了,有兴趣的小伙伴自己去了解一下吧。然后我接下来就讲一讲我这几个月使用angular遇到的一些坑,还有对angular的一些看法。
(1):数据绑定的闪烁问题,当你使用"{{}}"进行双向绑定的时候,当页面刷新速度过快,angular还没来得及把数据更新到页面上的时候,页面会显示“{{data}}”这种源代码的数据出来,解决这个问题有两个方法:一个是用ng-bind代替“{{}}”,另一个就是给标签加多一个属性 “ng-cloak”,这样就可以解决这个问题了。
(2):ng-repeat的问题,ng-repeat固然好用,可是有一个问题就是当你的数据重复的时候它会报错,例如你的数据是 [1,1,4];数组里的数组出现了重复的情况,这个时候angular就会报错,因为数据重复了,它监测到已经渲染过了,所以遇到重复的数据就会报错,这个时候就就需要在ng-repeat语句里面加一些东西:
<li ng-repeat = ‘list in list track by $index‘>{{list}}</li>
加了track by $index指定了angular追踪数组是根据$index的,因为$index是不会有相同的,所以这个时候就不会报错了。小伙伴使用的时候需要注意这点。当你的数据是json格式的时候,你可以使用你json数组里面某一个变量来替代$index,具体的小伙伴去试试吧。
(3):有时候你更新了数据,可是页面却没有更新,这种情况主要是发生在你自定义directive里面改变数据的时候,这个时候解决的方法就是手动调用$apply叫angular更新页面。
(4):当你在controller一个函数调用另外一个函数的使用顺序的问题
angular.module(‘myApp‘,[]) .controller(‘mainCtrl‘,function($scoe){ $scope.test = (function(){ $scope.test1(); })(); $scope.test1 = function(){ alert(1); } })
上面代码的这种情况是调用不成功的,当你把函数test1调到函数test上面的时候就可以调用了,不过这种情况只存在于你的第一个调用的函数不是通过事件来驱动的,就是说你有时候需要一开始进入某个页面就要执行某些操作,这个时候你就会用一个自执行函数完成,这个时候你这个自执行函数里面再调用别的函数就需要考虑定义函数顺序的问题了。如果像上面的代码,test函数是通过某个事件(如点击)来触发的,这个时候就不需要考虑函数定义顺序的问题了。