参考:http://www.jb51.net/article/60490.htm
数据绑定
这是到目前为止AngularJS最令人瞩目的特性了,在数据绑定方面它舍弃了对DOM的操作方式,而这一切都是由AngularJS来自动更新视图,你不必写操作dom的代码,在jQuery中,我们常常按照以下方式响应事件并修改视图:
$.ajax({ url: '/myEndpoint.json', success: function ( data, status ) { $('ul#log').append('<li>Data Received!</li>'); } });
相对于这样一个视图
< ul class="messages" id="log"> < /ul>
除了混杂的问题之外,我们还存在我之前提到的如何表明自己意图的问题。但是更为重要的是,我们必须人工手动去引用并更新这个DOM节点,如果我们想删除其中一条,那么必须以编程方式去操作那个DOM元素,那么在这种情况下我们怎么去测试DOM节点之外的逻辑呢,亦或者我们想改变展示方式呢?
以上代码显得凌乱又脆弱,但是在AngularJS中,我们可以这样做:
$http( '/myEndpoint.json' ).then( function ( response ) { $scope.log.push( { msg: 'Data Received!' } ); });
我们的视图应该像下面这样
< ul class="messages"> <li ng-repeat="entry in log">{{ entry.msg }}</li> < /ul>
在那种情况下,我们的视图也可以这样
< div class="messages"> <div class="alert" ng-repeat="entry in log"> {{ entry.msg }} </div> < /div>
现在我们不使用ul,而是使用Bootstrap的弹出框,但是我们不用修改controller中的代码,更为重要的是,不管是数据如何修改,视图层也会自动随之发生变化,非常简洁!
尽管我这里不会做演示,但是你需要知道数据绑定是双向的,你可以编辑数据通过添加指令<input ng-model="entry.msg" />,此外还有很多其他的令人兴奋的地方。
以测试驱动的开发
但是在AngularJS中我们可以关注分离点,所以我们可以做一些测试驱动的开发。例如,我们有一个directive用来说明在menu中我们的当前路径,我们可以在视图中这样声明:
<a href="/hello" when-active>Hello</a>
好了,现在我们可以写一个测试用来测试这个不存在的指令when-active了。
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(); }));
我们直接run测试用例,你会发现是失败的,这时候需要创建这个指令,如下:
.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' ); } }); } }; });
从概念上讲,指令不是打包的jQuery
某些指令仅仅是装饰我们的视图(例如ngClass),因此有时候直接操作dom是可以的,但是当一个指令类似于一个小物件并且拥有自己的模板,那么它应该当做一个分离的关注点,这就是说,它的模板需要和link中的执行逻辑以及其他controller函数分离开。
AngularJS拥有一整套的工具可以是这种分离更简单,使用ngClass指令,我们可以动态地更新class,使用ngBind我们可以进行双向数据绑定,使用ngShow和ngHide 我们
可以采用编程的形式显示和隐藏一个元素,也包括我们自己写的很多指令。换句话说,我们可以不用Dom操作而完成所有工作,dom操作越少,指令越容易测试,越容易指定他们的style属性,就越容易在将来改变他们,那么他们就越容易复用和分发。
我看过很多AngularJS新手使用指令封装一大串 jQuery代码,换句话说,既然我不能在controller里面进行dom操作,那么我可以将他放在指令中,虽然这相对于直接操作dom好很多,但是任然是错误的。
看看我们在上面的记录,即使我们将其放在一个指令中,我们任然需要以Angular的方式去操作它,这种方式不执行dom操作!在很多时候dom操作是需要的,但是这种情况比你想的要少得多。当我们需要做dom操作的时候先问问自己这里是否必须这样做,这才是一种更好的方式。