初识AngularJS
来源:互联网 发布:数学公式编辑器 知乎 编辑:程序博客网 时间:2024/05/24 01:39
在使用了AngularJS重构团队内部的平台之后,一直想总结点什么,这里先说说学习和使用AngularJS的感受。AngularJS是一款开源的JavaScript MV*(MVW、MVVM、MVC)框架,目前由Google维护。AngularJS弥补了HTML在构建应用方面的不足,其通过使用标识符(directives)结构,来扩展Web应用中的HTML词汇,使开发者可以使用HTML来声明动态内容,从而使得Web开发和测试工作变得更加容易。
AngularJS的创始人Misko是这样来描述框架诞生的历史的:AngularJS最初是作为一个编外项目(side project),当时我想去看看是否有可能让Web设计师(非开发者)只使用HTML标签来创建简单的应用程序。随着时间的推移,AngularJS演变成了一个全面的开发框架。AngularJS的设计理念是:构建UI应该是声明式的,这样的灵感来自于Misko在Adobe公司从事Flex方面工作的时候。
谈谈我个人使用的感受吧:最大的区别是对开发流程的影响,以往我想做一个Web应用,会先用纯Html构造原型,所有的数据均是假数据,静态的写到Html文件中,然后不断的调试CSS样式。待页面整体的展示让我满意之后,就开始Js与服务器的交互开发,并初步把页面的假数据替换掉,绑定成Js调用Ajax的返回。然而在使用到Table / List等数据加载的时候,我通常会在Js中来构造这些Dom元素。随着应用的庞大和复杂,我发现我在Js中构造了大量的Dom元素,下面是一个例子:
function buildPersonHtml(data){ var html = []; data = data[0]; for(var id in data){ var count = 0; if(data[id].length==0) continue; html[html.length] = '<div class="person alert alert-success">'; html[html.length] = '<span><i class="icon-user"></i> '+id+' 的任务列表:</span>'; html[html.length] = '<table class="table table-bordered">'; html[html.length] = '<thead><tr><th>时间</th><th>功能点</th><th>详细情况</th><th>完成进度</th><th>耗时</th><th>备注</th>'; html[html.length] = '</tr></thead><tbody>'; orderSubTask(data[id]); for(var i=0; i<data[id].length;i++){ var subtask = data[id][i]; if(subtask.progress != '100%') count ++; html[html.length] = '<tr>'; if(subtask.status=='end') html[html.length] = '<td>开始: '+betterDate(subtask.createTime)+'<br/>结束: '+betterDate(subtask.endTime)+'</td>'; else html[html.length] = '<td>开始: '+betterDate(subtask.createTime)+'</td>'; html[html.length] = '<td>'+subtask.name+'</td>'; html[html.length] = '<td>'+subtask.content.replace(new RegExp('\n','g'),'<br/>')+'</td>'; html[html.length] = '<td>'+subtask.progress+'</td>'; html[html.length] = '<td>'+subtask.time+'</td>'; html[html.length] = '<td>'+subtask.note+'</td>'; html[html.length] = '</tr>'; } html[html.length] = '</tbody></table>'; html[html.length] = '<span style="margin-top:-15px"><i class="icon-tasks"></i> 已完成任务:'+ (data[id].length-count)+ ' <i class="icon-tasks"></i> 当前任务数:'+count+'</span>'; html[html.length] = '</div>'; } return html.join('');}随着我构造这些Dom元素的Js代码越来越多,我的原型Html页面的内容也就越来越少,少到最后很可能就只有一个header一个footer和一个空的div而已,其他所有内容,都是Ajax从服务器读取,拿到Json对象的返回之后,才开始构建Dom加载。
接下来,在使用AngularJS重构的时候,我发现页面的原型设计好之后,基本上不需要做什么改变,即所有的Dom元素,页面上该看到的东西,都在你的Html中声明出来了。仅仅看Html文件,任何人都能知道这个页面大概有哪些元素(表单、表格等各种UI控件),然后AngularJS用ng-model的方式让你把这些Dom元素和数据进行了一种双向绑定,即把你的数据(Data Model)声明到页面中。(我觉得这一步完全有可能由Web设计师来完成)下面的代码片段是一个例子:
<table class="table table-bordered table-hover" ng-controller="MachineCtrl"> <tr> <th ng-click="machineKey = 'host'; reverse = !reverse" class="order-th">主机名</th> <th ng-click="machineKey = 'address'; reverse = !reverse" class="order-th">IP地址</th> <th>配置</th> <th>账号</th><th>OS</th> <th>软件</th> <th>备注</th> <th ng-click="machineKey = 'owner'; reverse = !reverse" class="order-th">使用者</th> <th>操作</th> </tr> <tr ng-repeat="machine in machines | filter:query | orderBy:machineKey:reverse"> <td class="nowrap">{{machine.host}}</td> <td class="nowrap">{{machine.address}}</td> <td>{{machine.hardware}}</td> <td>{{machine.name}} / {{machine.password}}</td> <td>{{machine.os}}</td> <td>{{machine.env}}</td> <td>{{machine.note}}</td> <td class="nowrap machine-owner" id="{{machine._id}}_owner"> <span>{{machine.owner}}</span> <input type="text" class="form-control owner-input" ng-keydown="bookMachine($event, machine._id)"/> <a class="owner-btn" ng-click="toggleOfflineBook(offline._id)"><i class="fa fa-times fg-lg"></i></a> </td> <td class="nowrap" ng-class="machine.status=='maintenance'?'disable':'enable'"> <span ng-click="maintainMachine(machine._id)"><i class="fa fa-cog fa-spin fa-lg"></i> 维护中...</span> <a title="订阅" ng-click="toggleMachineBook(machine._id)"><i class="fa fa-pencil"></i></a> <a title="维护" ng-click="maintainMachine(machine._id)"><i class="fa fa-wrench"></i></a> <a title="编辑" ng-click="editMachine(machine._id)"><i class="fa fa-edit"></i></a> <a title="删除" ng-click="deleteMachine(machine._id)"><i class="fa fa-trash-o"></i></a> </td> </tr> </table>可以看到我把一个table与叫machines的data model做了一个双向绑定,而实际上machines就是一个Json数组而已,当你用Js从服务端取到数据,填充了叫machines的Json数组之后,这个table就会自动更新出来,每一行展示一个machine,每一个单元格展示machine上的某个属性。所谓的双向绑定,即一方产生变化的时候,另外一方就会同步更新。所以如果我在Js文件中操作改变了这个machines数组对象,例如删除了其中一个元素那么页面table就会自动减少一行,更新了一个元素的属性值,table也会自动更新。就感觉像页面的声明model是Js中Json对象的引用一样,当Json对象发生任何变化,页面的model引用也会随之改变。
当具有这种特性之后,我的Js代码就可以专注对Model的管理和操作了,不需要再关心页面的“数据”角色,页面真正意义上充当了一个View的角色,我也不需要在Js中再去操作页面上的数据和重构Dom元素之类的。(你可以选择用jQuery.post,或者socket.io与服务器通信,在Js中维护Json对象的变化)当然,这种data-model binding并不是随意的,而是分作用域的,某些model只在一定范围的Html中可见。而控制这些作用域的就是ng-controller,即MVC中的C部分。
上面的Html中我将table声明绑定了一个叫MachineCtrl的Controller,那么machines这个model就只在这个table内可见。而Js中能操作它的也只有MachineCtrl这个Controller。我的Js关于MachineCtrl的代码片段如下:
/*** Machine Controller**/machineApp.controller('MachineCtrl', function($scope, socket){ ... socket.on('machine list', function (data) { $scope.machines = data; }); $scope.editMachine = function(id){ var entity = $scope.findMachine(id); var cloneEntity = cloneMachine(entity); loadMachine(cloneEntity,'test'); } $scope.bookMachine = function(e, id){ if(e.keyCode == 13){ var input = $('#'+id+'_owner input'); var owner = $.trim(input.val()); var entity = $scope.findMachine(id); if(owner == entity.owner){ error('重复订阅,忽略此次订阅!'); $scope.toggleMachineBook(id); return; }else if(entity.owner.length !=0 && owner.length!=0){ error('机器已经被订阅,请先取消订阅'); return; } socket.emit('bookMachine',{'id': id, 'owner': owner}); e.preventDefault(); }else if(e.keyCode == 27){ $scope.toggleMachineBook(id); e.preventDefault(); } }...当我用socket.io从服务端取到machines的Json对象之后,直接复制到MachineCtrl的$scope.machines上,这样就实现了与页面UI声明了MachineCtrl里的machines的双向绑定。之后我与服务器交互,就在MachineCtrl中更新$scope.machines实现增删改查,页面就会自动响应更新。
总结:AngularJS确是一个很强大的Javascript前端MVC框架,如今的互联网时代,对于富客户端需求越来越旺盛,前端Js和Dom的交互越来越复杂,AngularJS很好的对它们进行了一种分层和维护管理。
- 初识AngularJS
- angularJS初识
- 初识AngularJS
- 初识AngularJS
- 初识angularJs
- 初识angularJs
- 初识AngularJS
- 初识AngularJS
- 初识AngularJS
- angularjs初识
- 初识AngularJS
- 初识AngularJS
- 初识AngularJS
- 初识AngularJS
- AngularJS 世界------初识Angularjs
- Angularjs 路由之初识
- AngularJS初识--作用域
- 初识AngularJs(1)
- 多线程之间及多进程间的通信
- ofstream 和ifstream的具体用法
- mysql exists用法
- C#串口接受数据跨线程操作控件(留存+备份)
- Win32 SDK中设置Hotkey
- 初识AngularJS
- error:只有静态常量整型数据成员才可以在类中初始化
- 一般处理程序中 引用Session 的值
- jquery.form.js 提交教会你怎样用ajaxForm
- 操纵系统ContentProvider实例
- 评C++primer---(亚马逊上的评论,感觉很深刻,有点启发)
- VS2010在经历一些更新后,建立Win32 Console Project时会出“error LNK1123” 错误
- MongoDB MapReduce 使用(一)
- matlab——reshape