AngularJS 使用 UI Router 实现表单向导


Posted in Javascript onJanuary 29, 2016

我们看到这项技术已经应用在了许多的网页上。比如购物车,注册表单,入职流程以及许多多步表单,让用户更容易在线填写表单。

下面我们将构建它:

 AngularJS 使用 UI Router 实现表单向导

使用UI Router,它能内嵌状态,为每个状态显示不同的view,我们能让多步表单变得相当的容易。

为了快速的理解UI Router是怎样工作的,看我们的文章:AngularJS使用UI-Router路由

让我们言归正传,开始创建我们的最棒的表单!

创建工程

创建工程有个模板结构. 需要个 布局文件 , 每个表单的视图文件, 格式文件, 以及JavaScript 文件.

下面就是文件清单,先创建好它们,接着在填充内容

- index.html
- form.html
- form-profile.html
- form-interests.html
- form-payment.html
- app.js
- style.css

每个表单-____.html表示层级结构中的html文件. 这些结构最终创建我们的表单结构.

我们的布局/模板文件 index.html

我们通过建立一个主文件来引入我们所需要的所有资源以开始我们的项目 ,这里我们使用 index.html 文件作为主文件

现在,我们加载我们所需的资源(AngularJS, ngAnimate, Ui Router, 以及其他脚本和样式表)并且设定一个 ui-view用来告知 UI Router 我们的视图需要显示到哪里。这里我们使用 Bootstrap 来快速应用样式。

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <!-- CSS -->
  <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootswatch/3.1.1/darkly/bootstrap.min.css">
  <link rel="stylesheet" href="style.css">
  <!-- JS -->
  <!-- load angular, nganimate, and ui-router -->
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js"></script>
  <script src="app.js"></script>
</head>
<!-- apply our angular app -->
<body ng-app="formApp">
  <div class="container">
    <!-- views will be injected here -->
    <div ui-view></div>
  </div>
</body>
</html>

完成所有文件的引入后,让我们进入 app.js 开始创建Angular应用和最基本的路由配置。 注意我们是如何把Angular App (formApp) 应用到 body 上面的。

创建我们的Angular App app.js

现在我们来创建应用和路由。 在一个大型应用中, 你肯定希望把你的Angular应用、路由、控制器分布到它们各自的模块中,但是为了完成我们的简单用例,我们将把它们都放到app.js这个欢乐的大家庭中。

 现在我们拥有了一个已经注入了ngAnimate和ui.router的应用。 我们同样也建立了相应的路由。注意我们是如何为每一个视图区域定义 url,视图文件(templateUrl) 和 控制器的。

form 将是我们的主视图区域。它同样有一个以 . 分割的子视图区域 form.profile。这种想法能实现在应用状态发生变化时(译者:可能是路由、queryString等),子视图将会在主视图区域中显示出来。(译者:而且可以作到仅更新子视图区域变化,记录子视图区域状态)。

我们将在下一节中进行演示。 现在我们需要为form以及它的子视图区域创建视图。

让我们从新建form.html开始。这个文件将会在我们剩下的表单视图文件中充当模板的作用,正如index.html被用作整个项目的总体模板一样。我们所要作的是在该文件中包含ui-view,这样可以使嵌套声明知道该在何处注入他们的视图。

<!-- form.html -->
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
  <div id="form-container">
    <div class="page-header text-center">
      <h2>Let's Be Friends</h2>
      <!-- the links to our nested states using relative paths -->
      <!-- add the active class if the state matches our ui-sref -->
      <div id="status-buttons" class="text-center">
        <a ui-sref-active="active" ui-sref=".profile"><span>1</span> Profile</a>
        <a ui-sref-active="active" ui-sref=".interests"><span>2</span> Interests</a>
        <a ui-sref-active="active" ui-sref=".payment"><span>3</span> Payment</a>
      </div>
    </div>
    <!-- use ng-submit to catch the form submission and use our Angular function -->
    <form id="signup-form" ng-submit="processForm()">
      <!-- our nested state views will be injected here -->
      <div id="form-views" ui-view></div>
    </form>
  </div>
  <!-- show our formData as it is being typed -->
  <pre>
    {{ formData }}
  </pre>
</div>
</div>

注意我们是如何第二次在项目中使用ui-view的。这就是UI Router伟大的地方:我们可以嵌套声明和视图。这能够在我们开发应用时提供给我们非常多的灵活性。关于UI Router视图的内容,请参见 官方文档。

添加基于状态的激活类

我们希望每一个状态按钮能够在他们被激活时展示。为了达到这个效果,我们将会使用UI Router提供的ui-sref-active。如果ui-sref和当前状态一致,则会添加我们指定的类。

为了给自己的表单添加验证,请参见AngularJS表单验证。

现在,你可能想知道我们的表单究竟看起来是什么样子。让我们打开浏览器看一眼。

AngularJS 使用 UI Router 实现表单向导

目前为止,我们并没有完全按照希望的那样得到所有的内容,但是这是一系列伟大事情的开端。让我们继续前进,添加一点样式,之后会添加一些嵌入视图和注释。

基础Stylingstyle.css

我们将设计我们的form-container和status-buttons来是我们的表单看起来更好。

/* style.css */
/* BASIC STYLINGS
============================================================================= */
body              { padding-top:20px; }
/* form styling */
#form-container        { background:#2f2f2f; margin-bottom:20px;
  border-radius:5px; }
#form-container .page-header  { background:#151515; margin:0; padding:30px; 
  border-top-left-radius:5px; border-top-right-radius:5px; }
/* numbered buttons */
#status-buttons         { }
#status-buttons a        { color:#FFF; display:inline-block; font-size:12px; margin-right:10px; text-align:center; text-transform:uppercase; }
#status-buttons a:hover     { text-decoration:none; }
/* we will style the span as the circled number */
#status-buttons span      { background:#080808; display:block; height:30px; margin:0 auto 10px; padding-top:5px; width:30px; 
  border-radius:50%; }
/* active buttons turn light green-blue*/
#status-buttons a.active span  { background:#00BC8C; }

现在我们的按钮更好看了并且更符合我们想要的了,接下来我们看下嵌套视图。

嵌套视图form-profile.html, form-interests.html, form-payment.html

这部分会比较简单。我们将定义不同的带有我们需要的输入框的视图。并且将他们绑定到formData对象以便我们能看到输入的数据。

下面是我们用于嵌套视图的视图文件:

表单概要视图

<!-- form-profile.html -->
<div class="form-group">
  <label for="name">Name</label>
  <input type="text" class="form-control" name="name" ng-model="formData.name">
</div>
<div class="form-group">
  <label for="email">Email</label>
  <input type="text" class="form-control" name="email" ng-model="formData.email">
</div>
<div class="form-group row">
<div class="col-xs-6 col-xs-offset-3">
  <a ui-sref="form.interests" class="btn btn-block btn-info">
  Next Section <span class="glyphicon glyphicon-circle-arrow-right"></span>
  </a>
</div>
</div>

表单兴趣视图

<!-- form-interests.html -->
<label>What's Your Console of Choice?</label>
<div class="form-group">
  <div class="radio">
    <label>
      <input type="radio" ng-model="formData.type" value="xbox" checked>
      I like XBOX
    </label>
  </div>
  <div class="radio">
    <label>
      <input type="radio" ng-model="formData.type" value="ps">
      I like PS4
    </label>
  </div>
</div>
<div class="form-group row">
<div class="col-xs-6 col-xs-offset-3">
  <a ui-sref="form.payment" class="btn btn-block btn-info">
  Next Section <span class="glyphicon glyphicon-circle-arrow-right"></span>
  </a>
</div>
</div>

表单支付视图

<!-- form-payment.html -->
<div class="text-center">
  <span class="glyphicon glyphicon-heart"></span>
  <h3>Thanks For Your Money!</h3>
  <button type="submit" class="btn btn-danger">Submit</button>
</div>

既然我们已经定义了这些视图,那么当我们浏览表单时,他们就会显示出来。同样我们用下一个按钮和ui-sref来连接每一个新视图.

当使用ui-sref时,你要连接到你路由中定义的state而不是URL。然后Angular会使用这个来为你构建href。

下面是我们表单目前的每一个页面。

 

AngularJS 使用 UI Router 实现表单向导

AngularJS 使用 UI Router 实现表单向导

AngularJS 使用 UI Router 实现表单向导

为了让我们的页面不同寻常,让我们加上动画效果。

让我们的表单产生动画效果

因为在项目开始的时候,我们已经加载了ngAnimate,它已经添加到需要动画的的类上了。当视图进入或退出的时候,它将自动添加类ng-enter和ng-leave。

现在我们所有做的就是通过样式形成我们最终的表单。为了理解Angular动画,这篇文章是一个很好的起点。

让我们进去css文件,将动画,并应用到我们的表单上

/* style.css */
/* ANIMATION STYLINGS
============================================================================= */
#signup-form      { position:relative; min-height:300px; overflow:hidden; padding:30px; }
#form-views       { width:auto; }
/* basic styling for entering and leaving */
/* left and right added to ensure full width */
#form-views.ng-enter,
#form-views.ng-leave   { position:absolute; left:30px; right:30px;
  transition:0.5s all ease; -moz-transition:0.5s all ease; -webkit-transition:0.5s all ease; 
}
/* enter animation */
#form-views.ng-enter      { 
  -webkit-animation:slideInRight 0.5s both ease;
  -moz-animation:slideInRight 0.5s both ease;
  animation:slideInRight 0.5s both ease; 
}
/* leave animation */
#form-views.ng-leave      { 
  -webkit-animation:slideOutLeft 0.5s both ease;
  -moz-animation:slideOutLeft 0.5s both ease;
  animation:slideOutLeft 0.5s both ease;  
}
/* ANIMATIONS
============================================================================= */
/* slide out to the left */
@keyframes slideOutLeft {
  to     { transform: translateX(-200%); }
}
@-moz-keyframes slideOutLeft {  
  to     { -moz-transform: translateX(-200%); }
}
@-webkit-keyframes slideOutLeft {
  to     { -webkit-transform: translateX(-200%); }
}
/* slide in from the right */
@keyframes slideInRight {
  from   { transform:translateX(200%); }
  to     { transform: translateX(0); }
}
@-moz-keyframes slideInRight {
  from   { -moz-transform:translateX(200%); }
  to     { -moz-transform: translateX(0); }
}
@-webkit-keyframes slideInRight {
  from   { -webkit-transform:translateX(200%); }
  to     { -webkit-transform: translateX(0); }
}

首先,确定视图离开或进去时,表单的样式,他们是绝对定位的。需要确认当视图进入的时候一个视图不会放到另一个视图的下面。

其次,应用我们的动画到.ng-enter和.ng-leave类

第三,用@keyframes定义动画。所有这些部分组合到一起,我们的表单就有了Angular动画,基于状态的UI Router和Angular数据绑定。

以上所述是小编给大家分享的AngularJS 使用 UI Router 实现表单向导的相关知识,希望对大家有所帮助。

Javascript 相关文章推荐
前端开发必须知道的JS之原型和继承
Jul 06 Javascript
JavaScript高级程序设计(第3版)学习笔记3 js简单数据类型
Oct 11 Javascript
javascript中为某个元素指定事件的三种方式
Aug 07 Javascript
js读取json的两种常用方法示例介绍
Oct 19 Javascript
jQuery实现iframe父窗体和子窗体的相互调用
Jun 17 Javascript
js判断iframe中元素是否存在的实现代码
Dec 24 Javascript
BootStrap中jQuery插件Carousel实现轮播广告效果
Mar 27 jQuery
Angular实现的内置过滤器orderBy排序与模糊查询功能示例
Dec 29 Javascript
jQuery实现鼠标移入移出事件切换功能示例
Sep 06 jQuery
微信小程序自定义tabbar custom-tab-bar 6s出不来解决方案(cover-view不兼容)
Nov 01 Javascript
JavaScript将数组转换为链表的方法
Feb 16 Javascript
JS数据类型判断的几种常用方法
Jul 07 Javascript
JavaScript数据结构与算法之链表
Jan 29 #Javascript
动态创建按钮的JavaScript代码
Jan 29 #Javascript
JavaScript数据结构与算法之栈与队列
Jan 29 #Javascript
javascript实现表单验证
Jan 29 #Javascript
jQuery实现横向带缓冲的水平运动效果(附demo源码下载)
Jan 29 #Javascript
JavaScript判断DIV内容是否为空的方法
Jan 29 #Javascript
基于javascript实现listbox左右移动
Jan 29 #Javascript
You might like
用在PHP里的JS打印函数
2006/10/09 PHP
php smarty模版引擎中变量操作符及使用方法
2009/12/11 PHP
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
php垃圾代码优化操作代码
2010/08/05 PHP
JS异常处理try..catch语句的作用和实例
2014/05/05 PHP
PHP实现的蚂蚁爬杆路径算法代码
2015/12/03 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
php基于curl实现的股票信息查询类实例
2016/11/11 PHP
PHP MYSQL简易交互式站点开发
2016/12/27 PHP
载入进度条 效果
2006/07/08 Javascript
js 绑定带参数的事件以及手动触发事件
2010/04/27 Javascript
js中return false(阻止)的用法
2013/08/14 Javascript
javascript同页面多次调用弹出层具体实例代码
2013/08/16 Javascript
js判断客户端是iOS还是Android等移动终端的方法
2013/12/11 Javascript
js实现select组件的选择输入过滤代码
2014/10/14 Javascript
理解JavaScript事件对象
2016/01/25 Javascript
canvas绘制多边形
2017/02/24 Javascript
Vue动画事件详解及过渡动画实例
2019/02/09 Javascript
微信小程序之侧边栏滑动实现过程解析(附完整源码)
2019/08/23 Javascript
layui实现数据表格隐藏列的示例
2019/10/25 Javascript
JS实现简易计算器
2020/02/14 Javascript
vue pages 多入口项目 + chainWebpack 全局引用缩写说明
2020/09/21 Javascript
[01:09]2014DOTA2国际邀请赛 TI4西雅图DOTA2 中国美女coser加油助威
2014/07/20 DOTA
Python创建xml文件示例
2017/03/22 Python
python利用正则表达式搜索单词示例代码
2017/09/24 Python
Python subprocess模块常见用法分析
2018/06/12 Python
Python 2/3下处理cjk编码的zip文件的方法
2019/04/26 Python
python线程中的同步问题及解决方法
2019/08/29 Python
python输入错误后删除的方法
2019/10/12 Python
Python操作Elasticsearch处理timeout超时
2020/07/17 Python
Python进行特征提取的示例代码
2020/10/15 Python
PHP开发的一般流程
2013/08/13 面试题
Linux内核的同步机制是什么?主要有哪几种内核锁
2013/01/03 面试题
党员组织生活会发言材料
2014/10/17 职场文书
分享CSS盒子模型隐藏的几种方式
2022/02/28 HTML / CSS
SpringBoot Http远程调用的方法
2022/08/14 Java/Android