bootstrap + angularjs + seajs构建Web Form前端2
bootstrap + angularjs + seajs构建Web Form前端(二)
回顾
上一篇讲解了引入bootstrap构建一个简单的登录页面,如何让angularjs自动启动并绑定视图,操作过程当中如何使用ui-bootstrap,继而完成简单功能后如何引入seajs后如何使ng手动启动。我会尽量把自己在学习当中遇到的问题以及如何解决分享给各位,如果大家有什么疑问或者想要达到的功能可以告诉我,我可以尝试去把效果做出来然后再下一篇文章分享给各位。
需要解决的问题
1、实现ajax form
2、构建菜单
实现ajax form
首先给$scope定义一个formData的对象,然后将formData内的属性绑定到对应的input上,html代码如下:
//html代码<input type="text"class="form-control input-lg" placeholder="用户名" required autofocus ng-model="formData.name"/><input type="password"class="form-control input-lg" placeholder="密码" required ng-model="formData.password"/>//js代码
$scope.formData ={};//这里可以不定义对应的name和password,也可以为{ name: '', password: '' }
完成绑定以后,当我么对input进行操作的时候,变化的值就会同步到formData中,反过来也是一样的。
接下来要使用一个类似jQuery.ajax的函数,在ng中叫做$http(nodejs中也是http),对于这个对象详细的介绍可以查看API,它一样提供了名为post的函数来实现ajax的交互,我们可以使用原来的ngClick方法来实现ajax,但是这样便没有办法让表单进行验证了,因此这里使用ngSubmit绑定在form表单上,然后将登录按钮类型改为submit,那么当表单有效的情况下,点击按钮就会触发ngSubmit的函数了,然后将原来的alerts删除,并加上根据后台返回的代码显示不同信息的提示信息,代码如下:
<formname="frmLogin"class="col-sm-offset-4 col-sm-4"role="form"ng-controller="HomeLoginController"ng-submit="submit()"><inputtype="text"class="form-control input-lg"placeholder="用户名"requiredautofocusng-model="formData.name"/><inputtype="password"class="form-control input-lg"placeholder="密码"requiredng-model="formData.password"/><buttonclass="btn-lg btn-primary btn-block"type="submit">登录</button><spanclass="text-danger"ng-show="responseCode"ng-bind="responseCode == 4 ? '账号被禁用!' : '帐号密码有误!'"></span></form>
ngModel和ngBind的区别:ngModel用来绑定input、select、textarea等form表单控件,ngBind是绑定文本内容的(不包括html,如果要绑定html需要使用ngBindHtml),这里大家会发现表述的时候使用的是ngSubmit、ngClick、ngModel等(这些都是ng定义的指令)但是在html中却写成了ng-submit、ng-click等,这是ng的一个规则(当我们自己定义指令的时候也是一样的规则,如menuContent在html内使用的时候要写成menu-content),跟jQuery的css是一样的,其次这里出现的ngShow指令是指当指定的值或表达式为真的情况下,该元素是显示的,否则隐藏,跟它对应的属性是ngHide,其次ngBind绑定的值也同样可以是值也可以是表达式(大部分指令的名字都是很容易理解的)。
然后改造submit函数来实现ajax form,但是这里需要注意的是ng提供的ajax跟jQuery的ajax有一些区别,需要注意如下两点:
- data参数是不能像jQuery那样直接使用json对象的(jQuery内部会将其转化成QueryString,即a=b&c=d的格式),如果使用json对象后台将无法取到表单内的任何值
- headers必须指定'Content-Type': 'application/x-www-form-urlencoded',否则无法识别为表单数据,跟上一点一样的结果
由于ng没有提供将对象转化为QueryString格式的函数,但是jQuery提供了,因此可以使用jQuery.Param,但是ng提供的ajax的优点是,如果返回的是json字符串,它会默认转成json对象,代码如下:
$scope.submit =function(){
$http.post('/mvc/Home/Login', $.param($scope.formData),{
headers:{'Content-Type':'application/x-www-form-urlencoded'}}).success(function(data){
$scope.responseCode = data.code;//1s后让错误消息隐藏
$timeout(function(){
$scope.responseCode =0;},1000);});};
这样实现了ng版的ajax form了,相对于jQuery.form的方式,ng版本的代码多一些但是只要抽取一个库就简单多了。
构建菜单
当成功登录后,用户菜单是必不可少的,但是UI组件并没有提供tree,因此这里需要我们自己去实现了,这里就以一个比较简单的树作为此次实现的目标吧,如图:

要实现以上的tree首先要认识ng的几个指令(directive),首先是第一篇用到的ngRepeat,这个指令简单的说就是对包含的HTML以模板的方式进行循环,循环体则为指定的数据源,代码如下:
<ulng-repeat="m in list"><ling-bind="m.name"></li></ul>
list指向Controller内的$scope.list,而m in list类似于foreach(var m in list)。但是使用以上的代码得到的却只是根节点而已,如果才能遍历节点的时候也遍历它的子节点呢?
由于ng提供给的指令无法实现以上的要求,那么只有自己自定义指令去完成这个功能了,自定义指令要在注册模块的时候调用directive来注册自定义的指令(官方API好不容易找到该方法的说明却在$compile内),注意命名依然是camelCase命名法,按照最初的想法在第一层ngRepeat内再嵌入自定义的指令并将数据指向children,代码如下:
//html<ul><es-tree data="list"><es-tree></ul> //js
angular.module('es.tree',[]).directive('esTree',function(){return{
replace:true,
restrict:'E',
scope:{
data:'='},template:['<li ng-repeat="m in data">',' <a href="#" ng-bind="m.name"></a>',' <ul>',' <es-tree data="m.children"></es-tree>',' </ul>','</li>',].join('')};});
以上directive方法返回对象的属性说明如下:
replace:表示template或templateUrl内的html是否替换指令元素(<es-tree>)
restrict:表示如何识别该指令(E:元素名 A:属性 C:class M:注释)
scope:作用域内的对象包含的属性或方法,key是属性名或方法名,value:必须的几个值(@:将属性内的文本值赋予key =:获取属性内对应的对象赋予key &:将属性内表达式的值赋予key),如果value的值加入了其他字符串如=dataSource则在使用的时候要变成<es-tree data-source="数据源字段">
template:该指令所编译成的html
其余的说明清查看API如果有不清楚的,可以给我留言,^_^。template使用数组只是为了排版好看而已,没有其他意思。
但是我们用以上的结构后,会出现RangeError: Maximum call stack size exceeded的异常,这是由于编译过程当中并不会判断children是否有效才进行生成的,因此就成了一个无限循环了。那么只能再将节点的生成拆分出另一个指令,然后再内部进行判断,当存在子节点的时候生成子节点,不存在的情况下只生成<a>的内容,代码如下:
//esTreetemplate:['<li ng-repeat="m in data">',' <es-tree-node data="m"></es-tree-node>','</li>',].join('')//节点指令
directive('esTreeNode',function($compile){return{
link:function($scope, $element, $attrs){var data = $scope.data;vartemplate=['<a href="#" ng-bind="data.name"></a>'];if(data.children && data.children.length){template.push('<ul>',' <es-tree data="data.children"></es-tree>','</ul>');}var html = $compile(template.join(''))($scope);
$element.replaceWith(html);},
restrict:'E',
scope:{
data:'='}};});
这次终于达到所要的效果了,那么怎么样实现点击一个节点的时候这个节点被选中而且是只能单个节点被选中呢,其实这个还是很简单的,只需要给<a>部分添加一个ngClick的事件,并且ngClass绑定一个bool的字段,然后在Controller内进行控制就可以了,代码如下:
//其他省略//esTree<a href="#" ng-class="{ selected: data.selected }" ng-bind="data.name" ng-click="select(data)"></a>//controller
controller('esTreeController',function($scope){
$scope.select=function(m){if($scope.$root.selectedNode)
$scope.$root.selectedNode.selected =0;
m.selected =1;
$scope.$root.selectedNode = m;};})
如果要绑定某些事件呢,类似于easyui提供的onSelect这样的函数呢,其实原理跟data是一样的,那么这里就不再阐述了,文章就到这里了,如果有什么错误请支持,谢谢!
bootstrap + angularjs + seajs构建Web Form前端2的更多相关文章
- bootstrap + angularjs + seajs构建Web Form前端(1)
bootstrap + angularjs + seajs构建Web Form前端(一) 简介 Bootstrap是Twitter推出的一个用于前端开发的开源工具包,它由Twitter的设计师Mark ...
- angularjs + seajs构建Web Form前端(一)
简介 Bootstrap是Twitter推出的一个用于前端开发的开源工具包,它由Twitter的设计师Mark Otto和Jacob Thornton合作开,是一个CSS/HTML框架. Angula ...
- angularjs + seajs构建Web Form前端(二)
回顾 上一篇讲解了引入bootstrap构建一个简单的登录页面,如何让angularjs自动启动并绑定视图,操作过程当中如何使用ui-bootstrap,继而完成简单功能后如何引入seajs后如何使n ...
- angularjs + seajs构建Web Form前端(三) -- 兼容easyui
回顾 在上一章中使用了angular实现了ajax form和树形结构,经过以上两章对于angular的大致使用,对于angular也有了初步的认识,接下来的内容只会对angular的一些用法做简单的 ...
- angularjs + seajs构建Web Form3
angularjs + seajs构建Web Form前端(三) -- 兼容easyui 回顾 在上一章中使用了angular实现了ajax form和树形结构,经过以上两章对于angular的大致使 ...
- seajs构建web申请书
随着开发项目的不断扩大,查找代码依赖关系复杂化,维护比较沉闷.记seajs有这种效果方面.果断尝鲜.解决两个问题:1)命名冲突 2)文件相关性 因为所在BG使用TAF服务,基于C++开发一套WSP w ...
- 前端开发利器: Bootstrap + AngularJS
http://blog.csdn.net/conquer0715/article/details/51181391 概述 在HTML5盛行的互联网时代,涌现诸多的前端html/css/js框架,基于其 ...
- 移动端 Web 开发前端知识整理
文章来源: http://www.restran.net/2015/05/14/mobile-web-front-end-collections/ 最近整理的移动端 Web 开发前端知识,不定期更新. ...
- [web建站] 极客WEB大前端专家级开发工程师培训视频教程
极客WEB大前端专家级开发工程师培训视频教程 教程下载地址: http://www.fu83.cn/thread-355-1-1.html 课程目录:1.走进前端工程师的世界HTML51.HTML5 ...
随机推荐
- 创建自定义的Middleware中间件
创建自定义的Middleware中间件 阅读目录 何为Middleware中间件 使用Inline方式注册Middleware 使用Inline+ AppFunc方式注册Middleware 定义原生 ...
- Redux基础
Redux 是一个状态容器 Redux 就像是作者自己的介绍,它不会为你提供任何的东西,它不会告诉你如何做路由,它只专注于应用程序状态,是一个 JavasSript 的状态容器,所有的状态的变化都是当 ...
- Android Activity和Fragment生命周期图
- 第15章 迭代器模式(Iterator Pattern)
原文 第15章 迭代器模式(Iterator Pattern) 迭代器模式(Iterator Pattern) 概述: 在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构 ...
- crm使用soap删除实体
//C# 代码: //DeleteEntityRequest request = new DeleteEntityRequest(); //request.LogicalName = "ne ...
- node.js高效操作mongodb
node.js高效操作mongodb Mongoose库简而言之就是在node环境中操作MongoDB数据库的一种便捷的封装,一种对象模型工具,类似ORM,Mongoose将数据库中的数据转换为Jav ...
- Windows RPC
转载 Windows RPC Demo实现 本文参考并整理以下相关文章 1. <远程过程调用> -百度百科 2. <RPC 编程> -http://www.ibm.com/de ...
- Java设计模式(八)观察者模式 迭代器模式
(十五)观察者模式 观察者模式,定义对象间一对多关系,一个对象状态发生改变,全部依赖于它的对象都收到通知而且自己主动更新,观察者与被观察者分开.比如邮件订阅.RSS订阅,假设有更新就会邮件通知你. i ...
- Access to the temp directory is denied. Identity 'NT AUTHORITY\NETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss
造成错误的原因是用bat代码清理系统垃圾时造成的权限丢失而引起的 错误描述 1.An error occurred creating the configuration section handler ...
- [Android]Parcelable encountered IOException writing serializable object (name = xxx)
Activity之间通过Intent传递值,支持基本数据类型和String对象及它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.short ...