修真院Web工程師零基礎全能課javascript
本節課內容css
AngularJs進階-表單與驗證html
主講人介紹html5
沁修,葡萄藤技術總監java
項目經驗豐富,擅長H5移動項目開發。angularjs
專一技術選型、底層開發、最佳代碼實踐規範總結與推廣。express
直播錄屏版json
傳送門: https://v.qq.com/x/page/k0705...bootstrap
文字解析版數組
大綱概述
簡單表單
增長css的表單
驗證
自定義驗證
在angularjs的開發中有一項必不可少的內容就是表單。
表單裏有大量控件,如input,radio,select等,表單就是這些控件的集合,能夠將相關的控件根據須要進行分組。
簡單表單
在過去的表單開發中每每是這樣:
須要給每個控件添加一個id,而後找到id所在的DOM,對DOM綁定一些事件,來處理用戶的操做,以及及時給予反饋。
但在angularjs中,咱們有雙向數據綁定的ngModel:
它提供了model和view之間的雙向數據綁定,大大的減輕了開發的工做量。
並且,ng中的form已經不是普通的form了,是一個被ng封裝過的指令:
能夠完成普通form沒法實現的功能,自帶強大的驗證功能。咱們直接來段簡單表單的代碼:
<divng-controller="MyCtrl"class="ng-cloak">
<formnovalidate> <!— 會阻止默認的html5驗證,由於效果實在不是很好,咱們但願本身來控制這一切。 —>
名字:<inputng-model="user.name"type="text"><br/>
Email:<inputng-model="user.email"type="email"><br/>
性別:<inputvalue="男"ng-model="user.gender"type="radio">男
<inputvalue="女"ng-model="user.gender"type="radio">女
<br/>
<buttonng-click="reset()">還原上次保存</button>
<buttonng-click="update(user)">保存</button>
<buttonng-click="clean()">清空</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
app.controller("MyCtrl",function($scope,$window) {
$scope.data={};
$scope.update=function(user) {
$scope.data=angular.copy(user);
};
$scope.reset=function() {
$scope.user=angular.copy($scope.data);
};
$scope.clean=function() {
$scope.user={};
}
});
</script>
// 不合法的值是不會進入user的
ngModel是表單中的核心指令,同時也是一個使用頻率很是很是高的指令:
它不止提供了數據綁定,還有驗證,樣式更新,數據格式化,編譯功能。
若是不設置ngModel,那麼angluar就沒法知道form.$valid的值是否爲真。
它的input控件自帶一些驗證選項:
<input
ng-model=""
[name=""]
[required=""]
[ng-required=""]
[ng-minlength=""]
[ng-maxlength=""]
[ng-pattern=""]
[ng-change=""]>
...
</input>
加上樣式的表單
ng在驗證輸入或表單的有效性的時候已經提供了一些默認類。
所以能夠編輯本身喜歡的的css,私有化的定製這些類來實現特定的場景應用
.ng-valid { }
.ng-invalid { }
.ng-pristine { }
.ng-dirty { }
/ really specific css rules applied by angular /
.ng-invalid-required { }
.ng-invalid-minlength { }
.ng-valid-max-length { }
那麼改造一下剛剛那個表單,讓它交互性更強:
<styletype="text/css">
input.ng-invalid.ng-dirty {
background-color:#fa787e;
}
input.ng-valid.ng-dirty {
background-color:#78fa89;
}
</style>
<divng-controller="MyCtrl"class="ng-cloak">
<formnovalidate>
名字:<inputng-model="user.name"type="text"required><br/>
Email:<inputng-model="user.email"type="email"required><br/>
性別:<inputvalue="男"ng-model="user.gender"type="radio">男
<inputvalue="女"ng-model="user.gender"type="radio">女
<br/>
<buttonng-click="reset()">還原上次保存</button>
<buttonng-click="update(user)">保存</button>
<buttonng-click="clean()">清空</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
app.controller("MyCtrl",function($scope,$window) {
$scope.data={};
$scope.update=function(user) {
$scope.data=angular.copy(user);
};
$scope.reset=function() {
$scope.user=angular.copy($scope.data);
};
$scope.clean=function() {
$scope.user={};
}
});
</script>
表單與控制器
在angualrjs中,ng-controller做用域當中的form表單,可使用name屬性將它暴露到scope中。
咱們再次來改造一下這個表單,給它加上一些簡單的驗證,要求是:
name必填
email必填
表單保存過就不能再保存
表單和保存的內容一致就沒法再保存
<divng-controller="MyCtrl"class="ng-cloak">
<formnovalidatename="formName">
名字:<inputng-model=「user.name」 name=「userName" type="text"required><br/>
<divng-show="formName.userName.$dirty&&formName.userName.$invalid">
<span>請填寫名字</span>
</div>
Email:<inputng-model=「user.email」 name=「emailName"type="email"required><br/>
<divng-show="formName.userEmail.$dirty && formName.userEmail.$invalid">提示:
<spanng-show="formName.userEmail.$error.required">請填寫Email</span>
<spanng-show="formName.userEmail.$error.email">這不是一個有效的Email</span>
</div>
性別:<inputvalue="男"ng-model="user.gender"type="radio">男
<inputvalue="女"ng-model="user.gender"type="radio">女
<br/>
<buttonng-click="reset()"ng-disabled="isUnchanged(user)">還原上次</button>
<buttonng-click="update(user)"ng-disabled="formName.$invalid || isUnchanged(user)">保存</button>
<buttonng-click="clean()">清空</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
app.controller("MyCtrl",function($scope,$window) {
$scope.data={};
$scope.update=function(user) {
$scope.data=angular.copy(user);
};
$scope.reset=function() {
$scope.user=angular.copy($scope.data);
};
$scope.clean=function() {
$scope.user={};
}
$scope.isUnchanged=function(user) {
returnangular.equals(user,$scope.data);
};
});
事實上是這樣的,ng的表單提供了不少屬性來幫助咱們驗證它
屬性class說明$validng-valid驗證是否經過$invalidng-invalid驗證是否未經過$pristineng-pristine表單和控件是否沒使用過$dirtyng-dirty表單和控件是否使用過
若是咱們要訪問表單屬性就能夠:
form-name.angular-property
若是是訪問輸入框屬性則能夠:
form-name.input-name.angular-property
若是想禁用表單按鈕,很是簡單,若是整個表單沒經過驗證,就會禁用,那就只須要加上這樣的代碼
ng-disabled="formName.$invalid」
這也說明,咱們input和form的name字段是必須加的,須要經過這樣的鏈式調用法訪問到屬性。
更漂亮的驗證
若是咱們給咱們的網站加上bootstrap,就可使用它提供的類,來圍繞咱們的表單作更好看的信息和顏色了。
這個時候咱們會用到ng-class,它容許咱們基於一個表達式來添加類。
好比若是輸入框的狀態是$invalid或者不是$pristine的話,咱們想要添加一個has-error類,就能夠這樣:
ng-class=「{<class>: <express>}"
<!-- USERNAME -->
<divclass="form-group"ng-class="{ 'has-error' : userForm.username.$invalid && !userForm.username.$pristine }">
<label>Username</label>
<inputtype="text"name="username"class="form-control"ng-model="user.username"ng-minlength="3"ng-maxlength="8">
<png-show="userForm.username.$error.minlength"class="help-block">Username is too short.</p>
<png-show="userForm.username.$error.maxlength"class="help-block">Username is too long.</p>
</div>
<!-- EMAIL -->
<divclass="form-group"ng-class="{ 'has-error' : userForm.email.$invalid && !userForm.email.$pristine }">
<label>Email</label>
<inputtype="email"name="email"class="form-control"ng-model="user.email">
<png-show="userForm.email.$invalid && !userForm.email.$pristine"class="help-block">Enter a valid email.</p>
</div>
自定義的驗證
ng爲表單驗證默認提供了一些directive,好比:
required,pattern,minlenth,maxlength,min,max。
但咱們能夠經過定義這些指令增長驗證規則。這些指令寫起來很好玩,同時它們也有一些規則須要掌握:
1.model更新到view的時候。
model發生的改變,都在ngModelController.$formatters數組中排隊執行,而後經過$setValidity去修改控件的驗證狀態
2.view更新到model的時候。
是這樣的,當用戶和控件發生交互,會觸發$setViewValue。
而後就須要執行$parsers數組中的方法,去從控件中獲得值,而後進行過濾或轉換或驗證。
<divclass="ng-cloak">
<formnovalidateclass="css-form"name="formName">
<div>
大小(整數 0 - 10):<inputintegertype="number"ng-model="size"name="size"min="0"max="10"/>{{size}}<br/>
<spanng-show="formName.size.$error.integer">這不是一個有效的整數</span>
<spanng-show="formName.size.$error.min || formName.size.$error.max">
數值必須在0到10之間
</span>
</div>
<div>
長度(浮點數):
<inputtype="text"ng-model="length"name="length"smart-float/>
{{length}}<br/>
<spanng-show="formName.length.$error.float">這不是一個有效的浮點數</span>
</div>
</form>
<pre>form = {{user | json}}</pre>
<pre>data = {{data | json}}</pre>
</div>
<scripttype="text/javascript">
varapp=angular.module("SimpleForm", []);
varINTEGER_REGEXP=/^-?d*$/;
app.directive("integer",function() {
return{
require:"ngModel",
link:function(scope,ele,attrs,ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if(INTEGER_REGEXP.test(viewValue)) {
ctrl.$setValidity("integer",true);
returnviewValue;
}else{
ctrl.$setValidity("integer",false);
returnundefined;
}
});
}
};
});
varFLOAT_REGEXP=/^-?d+(?:[.,]d+)?$/;
app.directive("smartFloat",function() {
return{
require:"ngModel",
link:function(scope,ele,attrs,ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if(FLOAT_REGEXP.test(viewValue)) {
ctrl.$setValidity("float",true);
returnparseFloat(viewValue.replace(",","."));
}else{
ctrl.$setValidity("float",false);
returnundefined;
}
});
}
}
});
</script>
以上就是上節課的內容解析啦