使用AngularJS實作表單精靈的方法_AngularJS
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
發布: 2016-05-16 15:53:43
今天我們將使用AngularJs和偉大的UI Router以及Angular ngAnimate module建立一個帶有動畫的多步驟表單。這項技術可以用在你想要簡化使用者操作的大表單上。
我們看到這項技術已經應用在許多的網頁上了。例如購物車,註冊表單,入職流程以及許多多步驟表單,讓使用者更容易在線上填寫表單。
下面我們將建構它:

使用UI Router,它能內嵌狀態,為每個狀態顯示不同的view,我們能讓多步驟表單變得相當的容易。
讓我們言歸正傳,開始創建我們的最棒的表單!
建立工程
建立工程有個範本結構. 需要個 版面配置檔案 , 每個表單的檢視檔, 格式檔案, 以及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 來快速套用樣式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <!-- 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這個歡樂的大家庭中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | angular.module( 'formApp' , [ 'ngAnimate' , 'ui.router' ])
.config( function ( $stateProvider , $urlRouterProvider ) {
$stateProvider
.state( 'form' , {
url: '/form' ,
templateUrl: 'form.html' ,
controller: 'formController'
})
.state( 'form.profile' , {
url: '/profile' ,
templateUrl: 'form-profile.html'
})
.state( 'form.interests' , {
url: '/interests' ,
templateUrl: 'form-interests.html'
})
.state( 'form.payment' , {
url: '/payment' ,
templateUrl: 'form-payment.html'
});
$urlRouterProvider .otherwise( '/form/profile' );
})
.controller( 'formController' , function ( $scope ) {
$scope .formData = {};
$scope .processForm = function () {
alert( 'awesome!' );
};
});
|
登入後複製
現在我們擁有了一個已經注入了ngAnimate和ui.router的應用。 我們同樣也建立了對應的路由。注意我們是如何為每個視圖區域定義 url,視圖檔案(templateUrl) 和 控制器的。
form 將是我們的主視圖區域。它同樣有一個以 . 分割的子視圖區域 form.profile。這種想法能實現在應用程式狀態改變時(譯者:可能是路由、queryString等),子視圖將會在主視圖區域中顯示出來。 (譯者:而且可以作到僅更新子視圖區域變化,記錄子視圖區域狀態)。
我們將在下一節中進行示範。 現在我們需要為form以及它的子視圖區域建立視圖。
表單範本檢視 form.html
讓我們從新建form.html開始。這個文件將會在我們剩下的表單視圖文件中充當範本的作用,就像index.html被用作整個專案的整體範本一樣。我們所要作的是在該文件中包含ui-view,這樣可以使嵌套聲明知道該在何處註入他們的視圖。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <!-- 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 class = "brush:php;toolbar:false" >
{{ formData }}
|
登入後複製
注意我们是如何第二次在项目中使用ui-view的。这就是UI Router伟大的地方:我们可以嵌套声明和视图。这能够在我们开发应用时提供给我们非常多的灵活性。关于UI Router视图的内容,请参见官方文档。
添加基于状态的激活类
我们希望每一个状态按钮能够在他们被激活时展示。为了达到这个效果,我们将会使用UI Router提供的ui-sref-active。如果ui-sref和当前状态一致,则会添加我们指定的类。
现在,你可能想知道我们的表单究竟看起来是什么样子。让我们打开浏览器看一眼。

目前为止,我们并没有完全按照希望的那样得到所有的内容,但是这是一系列伟大事情的开端。让我们继续前进,添加一点样式,之后会添加一些嵌入视图和注释。
基础Stylingstyle.css
我们将设计我们的form-container和status-buttons来是我们的表单看起来更好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | body { padding-top:20px; }
#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; }
#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; }
#status-buttons span { background:#080808; display:block; height:30px; margin:0 auto 10px; padding-top:5px; width:30px;
border-radius:50%; }
#status-buttons a.active span { background:#00BC8C; }
|
登入後複製
现在我们的按钮更好看了并且更符合我们想要的了,接下来我们看下嵌套视图。
嵌套视图form-profile.html, form-interests.html, form-payment.html
这部分会比较简单。我们将定义不同的带有我们需要的输入框的视图。并且将他们绑定到formData对象以便我们能看到输入的数据。
下面是我们用于嵌套视图的视图文件:
表单概要视图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!-- 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>
|
登入後複製
表单兴趣视图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <!-- 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>
|
登入後複製
表单支付视图
1 2 3 4 5 6 7 | <!-- 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。
下面是我们表单目前的每一个页面。



为了让我们的页面不同寻常,让我们加上动画效果。
让我们的表单产生动画效果
因为在项目开始的时候,我们已经加载了ngAnimate,它已经添加到需要动画的的类上了。当视图进入或退出的时候,它将自动添加类ng-enter和ng-leave。
现在我们所有做的就是通过样式形成我们最终的表单。为了理解Angular动画,这篇文章是一个很好的起点。
让我们进去css文件,将动画,并应用到我们的表单上
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #signup-form { position:relative; min-height:300px; overflow:hidden; padding:30px; }
#form-views { width:auto; }
#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;
}
#form-views.ng-enter {
-webkit-animation:slideInRight 0.5s both ease;
-moz-animation:slideInRight 0.5s both ease;
animation:slideInRight 0.5s both ease;
}
#form-views.ng-leave {
-webkit-animation:slideOutLeft 0.5s both ease;
-moz-animation:slideOutLeft 0.5s both ease;
animation:slideOutLeft 0.5s both ease;
}
@keyframes slideOutLeft {
to { transform: translateX(-200%); }
}
@-moz-keyframes slideOutLeft {
to { -moz-transform: translateX(-200%); }
}
@-webkit-keyframes slideOutLeft {
to { -webkit-transform: translateX(-200%); }
}
@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数据绑定。