directive指令二 require:'^ngModel'

本章主要是講指令與ngModel的交互。json

在angular有一個內置指令叫ngModel,它是angular用來處理表單的最重要的指令。在源碼中,頁面上的model值的格式化、解析、驗證都是由ngModel指令所對應的控制器ngModelController來實現的。ngModelController提供了不少方法和屬性,咱們能夠經過自定義指令的require:'ngModel'來獲取內置指令ngModel的ngModelController,進而在link函數裏對操做ngModelController的方法和屬性。api

接下來具體講一下ngModelController的方法和屬性,以及它們的具體用法。promise

 

1.兩個核心屬性$viewValue和$modelValue 
$viewValue是指令渲染模板所用的值,而$modelValue是在控制器中流通的值。不少時候這兩個值是不同的。好比說,當頁面上展現了一個日期,顯示的多是"2018/04/23",可是這個字符串在控制器中對應的值多是一個js的Date對象的實例。
app

 

2.三個核心管道$formatters $parses $validators 和$asyncValidators 異步

 

angular除了提供$viewValue和\modelValue以外,還提供了兩個用來處理它們的方法,分別是$parses和$formatters。 
$parsers:由view值到model值的轉換器,用戶輸入的變化會觸發其中的管道函數,頁面上的model值由管道函數中的return值決定。 
$formatters:和$parsers的做用相反,它是model值到view值的轉化器,其view值由對應的管道函數中的return值決定。 
$validators: 是一個json對象
async

{
   validateName: function(modelValue,viewValue){
       return ...
   }
}

當$setViewValue(value)被賦值給$modelValue以前,會通過$parsers管道,通過$parsers管道時,就會通過這個$validators管道。其中,validateName是驗證器的名稱,其中的參數modelValue和viewValue就是和viewValue,若是返回值是true,則經過validateName。 
自定義一個驗證器:
函數

<div class="alert alert-danger" role="alert" ng-show="myForm.myWidget.$error.validCharacters">
    <strong>Oh!</strong> 不符合自定義的驗證規則!
</div>
ngModel.$validators.validCharacters = function(modelValue, viewValue) {
    var value = modelValue || viewValue;
    return /[0-9]+/.test(value);
};

$asyncValidators:也是一個json對象,不過能夠用來處理異步驗證。ui

<input validate-name type="text" name="myWidget" ng-model="userContent" ng-model-options="{updateOn:'blur'}" class="form-control" required uniqueUsername>

<div class="alert alert-danger" role="alert" ng-show="myForm.myWidget.$error.uniqueUsername">
      <strong>Oh!</strong> 已經存在的用戶名!
</div>
app.directive('validateName',function($http,$q){
    return {
        restrict:'A',
        require:'?^ngModel',
        link:function(scope,iele,iattr,ctrl){
            ctrl.$asyncValidators.uniqueUsername = function(modelValue, viewValue) {
                var value = modelValue || viewValue;
                // 異步驗證用戶名是否已經存在
                return $http.get('/api/users/' + value).
                then(function resolved(res) {
                    if(res.data){
                        //用戶名已經存在,驗證失敗,給下一個promise傳遞失敗通知.
                        return $q.reject('res.data');
                    }
                    else {
                        //用戶名不存在,驗證成功.
                        return true
                    }

                }, function rejected() {
                        //請求失敗
                })
            };
        }
    }
});

 

3.兩個核心方法$setViewValue()和$render() 
$setViewValue(): 更新視圖值。緣由是每一個input的輸入事件都會調用這個方法。可是若是value是一個對象,而不是字符串或數值,那麼咱們在用該方法傳入值以前應該先拷貝一份,由於ngModel不會深刻檢測對象的變化,它只看對象的引用是否發生變化。若是隻是改變了對象的某個屬性,也不會去通過$parsers和$validators管道。執行$setViewValue()方法,不會觸發$digest。 
$render():在視圖須要被更新的時候調用。因爲ngModel的對比機制,$render()只在$modelValue和$viewValue都發生了實際的改變, 纔會會被調用。也就是說,$render函數負責將模型值同步到視圖上。
spa

 

來看一下指令和控制器及其內部運做如圖: 
ngModelController.PNG-49.8kB
rest

 

 

還有一些經常使用屬性

屬性 說明
$error json對象。就是全部驗證失敗的驗證名和失敗信息組成的json對象。
$pending json對象。正在進行中的異步驗證會被放在這個對象裏。
$untouched 布爾值。若是元素尚未失去過焦點,那這個值就是true。
$touched 布爾值。若是元素已經失去過焦點,那這個值就是false。
$pristine 布爾值。若是元素尚未和用戶發生過交互,那這個值就是true。
$dirty 布爾值。若是元素已經和用戶發生過交互,那這個值就是true。
$valid 布爾值。這個也很經常使用,就是當全部驗證(異步同步),都經過的時候,它就是true。
$invalid 布爾值。這個也很經常使用,就是當全部驗證(異步同步),其中有一個或一個以上驗證失敗,它就是true。
$name 字符串。很簡單,就是獲取元素的name屬性。
$isEmpty 當咱們須要判斷input的value值是否爲空的時候,可使用這個方法。
相關文章
相關標籤/搜索