angular指令中的require: 'ngModel'


在說require之前,先看一下scope

指令scope: false, true,{}:
1. false:默認使用controller的scope;<br>
2. true:獨立作用域,但是包含父scope的屬性和方法;
3. {} 使用獨立的scope;<br>
3.1. 綁定父作用域的scope,請參考綁定策略;

 

require表示需要依賴的指令;如果有依賴的指令,那么link的第四個參數也就是依賴指令的對外暴露的controller也自動會被注入進來

require選項的值可以分別用前綴?、^ 和?^進行修飾,也可以不修飾。
如果不進行修飾,比如require:'thisDirective',那么require只會在當前指令中查找控制器
如果想要指向上游的指令,那么就是用^進行修飾,比如require:'^parentDirective',如果沒有找到,那就會拋出一個錯誤。
如果使用?前綴,就意味着如果在當前指令沒有找到控制器,就將null作為link的第四個參數;
那么,如果將?和^結合起來,就可以既指定上游指令,又可以在找不到時,不拋出嚴重的錯誤。

 

自定義指令是當使用require:‘ngModel’ 這個選項來增強對表單的操作,這樣ngModel就可以作為link選項的第四個參數,

 link: function (scope,iElem,iAttr,ngmodel){
              //其他邏輯代碼
         }

  首先讓在控制台輸出ngmodel這個參數看看,代碼如下

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="angular.js" charset="utf-8"></script>
</head>
<body ng-controller='ctrl'>
    <input type="text" test ng-model=_val>
    <script>
        var app = angular.module('app',[]);
        app.controller('ctrl',function ($scope){
            $scope._val = "leifengshushu";
        })
        app.directive('test',function(){
            return{
                restrict: 'AE',
                require: 'ngModel',
                link: function (scope,iElem,iAttr,ngmodel){
                    console.log(ngmodel)
                }
            }
        })
    </script>
</body>
</html>

可以看到這個對象包含很多屬性和方法,

1.

$viewValue為視圖值,即顯示在視圖(頁面)的實際值(就是上面例子中input輸入框的值)

$modelValue為模型值,即賦給ng-model的值(與控制器綁定的值)

兩者不一定相等,因為$viewValue同步到$modelValue要經過一系列的操作(經過三個管道)。

雖然大多數情況下兩者是相等的(例如上面的例子)

 2.

$parsers為一個執行它里面每一個元素(每一個元素都是一個函數)的數組,

主要是用來做驗證和轉換值的過程,

ngModel從DOM讀取的值會被傳入到其中的函數

它會依次執行每一個函數,把每一個函數執行的結果傳個下一個函數,

而最后一個函數執行的值將會傳到model中,

可以將函數push進去,那樣它就會執行。

3.

$formatters也是一個執行它里面每一個元素(每一個元素都是一個函數)的數組,

主要用來對值進行格式化和轉換,以便在綁定了這個值的控件中顯示。

當數據的模型值發生變化的時候,里面的函數會被一一執行,

同樣就可以將函數push進去,讓它執行

4.

$viewChangeListeners的值也是一個由函數組成的數組

當視圖的值發生變化的時候里面的函數會被一一調用,

實現跟$watch類似的功能。

5.

$render函數負責將模型值同步到視圖上, 如果模型值被改變,需要同步視圖的值。

6.

$setViewValue用於設置視圖值(上面的例子就是將input的value值賦值給$viewValue)

7.

$error 一個包含所有error的對象

8.

$setPristine 設置為原始狀態,會添加ng-pristine的class類名,移除ng-dirty的class類名

9.

$setValidity 來設置錯誤的標志

為一個函數,接受兩個參數,第一個參數為錯誤標志的名字,是字符串類型,將會被設置成$error的屬性

第二個參數為布朗值,為這個錯誤標志的值。

在控制台中打印出來ngmodel.$setValidity看看

function (validationErrorKey, isValid) {
    // Purposeful use of ! here to cast isValid to boolean in case it is undefined
    // jshint -W018
    if ($error[validationErrorKey] === !isValid) return;
    // jshint +W018

    if (isValid) {
      if ($error[validationErrorKey]) invalidCount--;
      if (!invalidCount) {
        toggleValidCss(true);
        this.$valid = true;
        this.$invalid = false;
      }
    } else {
      toggleValidCss(false);
      this.$invalid = true;
      this.$valid = false;
      invalidCount++;
    }

    $error[validationErrorKey] = !isValid;
    toggleValidCss(isValid, validationErrorKey);

    parentForm.$setValidity(validationErrorKey, isValid, this);
  }

可以了解到執行了ngmodel.$setValidity會影響到$invalid和$valid的值,

另外從上面代碼中$error[validationErrorKey] = !isValid;可以知道,

執行之后,$error對象中的錯誤標志validationErrorKey為 設置的布朗值isValid的相反值。

 

用通俗的話講,用法就是ngmodel.$setValidity('flag',布朗值)

這樣就可以在頁面上用formname.inputname.$error.flag,例如:

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="angular.js" charset="utf-8"></script>
</head>
<body ng-controller='ctrl'>
    <form action="" name='myform'>
        <input type="text" test ng-model=_val name='jie'>
        <div ng-show='myform.jie.$error.empty'>empty!!</div>
    </form>
    <script>
        var app = angular.module('app',[]);
        app.controller('ctrl',function ($scope){
            $scope._val = "leifengshushu";
        })
        app.directive('test',function(){
            return{
                restrict: 'AE',
                require: 'ngModel',
                link: function (scope,iElem,iAttr,ngmodel){
                    scope.$watch(function(){return scope._val},function(){
                        if(ngmodel.$isEmpty(ngmodel.$viewValue)){
                            ngmodel.$setValidity('empty',false); //注意到這里設置為false,而$error.empty則會顯示為true
                            console.log(ngmodel.$error);
                        }
                    })
                    //console.log(ngmodel.$setValidity);
                }
            }
        })
    </script>
</body>
</html>

當你清空input里的值時候,這時候

 <div ng-show='myform.jie.$error.empty'>empty!!</div>

就會顯示出來。

10.

$name 的值為input的name屬性的值,如下

<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="angular.js" charset="utf-8"></script>
</head>
<body ng-controller='ctrl'>
    <input type="text" test ng-model=_val name='jie'>
    <script>
        var app = angular.module('app',[]);
        app.controller('ctrl',function ($scope){
            $scope._val = "leifengshushu";
        })
        app.directive('test',function(){
            return{
                restrict: 'AE',
                require: 'ngModel',
                link: function (scope,iElem,iAttr,ngmodel){
                    console.log(ngmodel);
                    console.log(ngmodel.$name); //輸出jie
                }
            }
        })
    </script>
</body>
</html>

11.

$$validityState(暫時不清楚用法,求解答~)

12.

$isEmpty(value) 函數,判斷是否為空

當 需要判斷input的value值是否為空的時候,可以使用這個方法

其實可以就當它是個判斷是否為空的方法,傳入一個參數,判斷這個參數是否為空,你傳入任何值都可以

要是需要,也可以自己在指令里重寫這個方法,來定義自己需要的“是否為空”的概念

 13. 

$pristine 如果用戶還沒有進行過交互,值是true.

$drity 如果用戶已經進行過交互,值是true.

 14.

$valid 如果沒有錯誤,值是true.

$invalid 如果有錯誤,值是true.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM