2014-06-23 132 views
5

我想使用AngularJS提供的內置表單驗證。但是,在我使用自定義指令的表單中,每個指令都有一個隔離範圍。因此,表單元素無法訪問綁定值。AngularJS表單驗證隔離範圍

任何想法如何解決這個問題?

或者,是否有可能使用AngularJS驗證而不使用表單?

ng-minlength和ng-required指令不觸發表單驗證。

<div ng-app="myApp" ng-controller="myCtrl"> 
    <form name="myForm" novalidate> 
     <do-something ng-model="variable"></do-something> 
     <h4 data-ng-if="myForm.myElement.$error.required">Please enter something</h4> 
     <h4 data-ng-if="myForm.myElement.$error.greaterThanOne">Please enter a value greater than 1</h4> 
     <h4 data-ng-if="myForm.myElement.$error.minLength">Please enter something longer than 1 digit</h4> 
    {{myForm.myElement.$error}}  
    </form> 
</div> 

var app = angular.module('myApp', []); 
app.controller('myCtrl', function ($scope) { 
}); 
app.directive('doSomething', function() { 
    return { 
     restrict: 'E', 
     require: '?ngModel', 
     scope: { 
      model: '=ngModel' 
     }, 
     template: 
      '<div>' + 
      ' <input name="myElement" ng-model="model" ng-required ng-minlength="1" />' + 
      '</div>' 
    } 
}); 

全部普拉克可以在這裏找到:下面是一個說明該問題的plunkr:http://plnkr.co/edit/iWyvX2?p=preview

+0

你有在傳遞價值,以你的指令屬性?您應該能夠將該特定值的範圍設置爲雙向我會想到的。儘管我在這裏做出假設;張貼小提琴。 –

+0

我已經發布了一個plunkr來說明這個問題。我已將該屬性傳遞給該指令。你能看到有什麼不對嗎? –

回答

2

從我的理解,是的,你必須使用表單驗證。

中,我確認是建立一個指令像下面

module.directive('ngDoSomething', function() { 
    restrict: 'A' 
    require: '?ngModel', 
    scope: { 
     model: '=ngModel' 
    } 
    link: function($scope, element, attrs, ngModel) { 
    $scope.$watch('model', function(val) { 
     ngModel.$setValidity('required', !!val); 
     ngModel.$setValidity('greaterThanOne', val > 1); 
    } 
}); 

然後使用HTML

<form name="somethingForm"> 
    <input name="somethingElement" data-ng-do-something data-ng-model="variable" /> 
    <h4 data-ng-if="somethingForm.somethingElement.$error.required">Please enter something</h4> 
    <h4 data-ng-if="somethingForm.somethingElement.$error.greaterThanOne">Please enter a value greater than 1</h4> 
</form> 

我希望這有助於

+1

我發佈了一個plunkr(http://plnkr.co/edit/iWyvX2?p=preview),它更清楚地說明了我遇到的問題。我讓你的代碼工作,但無法讓我的工作。有任何想法嗎? –

+1

@DanielMackay我在你的例子中有一種感覺myForm.myElement將無法解決(由於隔離範圍)。是否有一個原因,你必須使用自定義模板而不是輸入的指令? –

+1

是的,原因是我使用的一些指令比單個輸入更復雜。我使用的大多數輸入指令都結合了標籤和輸入。有些甚至更復雜,就像我們擁有的自定義單選按鈕。 –

2

好了丹尼爾的樣子,我很感興趣所以我進一步研究了一下。你的代碼和@ user3766487之間的主要區別在於你使用了一個指令元素和注入模板。我相信這引起了一些模糊(你會看到指令本身和注入輸入元素都具有相同的名稱屬性)。模型的鏈接似乎也不是很有效。

我已經改變了你的代碼來替換模板,這使事情變得更簡單了。它似乎工作:

(1)更改屬性名稱 「使用MINLENGTH」(而不是 「的minLength」):與這2種變化預期

http://plnkr.co/edit/eTSbjNe4KXW9IbUKtKuG

+0

感謝您的幫助@ChrisBell。我想我們正在慢慢到達那裏。是否可以使用標準的角度驗證指令(例如ng-maxlength)?或者你總是必須使用$ setValidity? –

0

的NG-驗證將工作:

<h4 data-ng-if="myForm.myElement.$error.minlength"> 

(2)設置NG-需要爲 「true」:

<input name="myElement" ... ng-required="true"> 

硒將minlength設置爲「1」不會執行任何操作,因爲表單驗證不會檢查輸入爲空的最小長度。如果設置使用MINLENGTH在輸入「5」,然後輸入一個字符,你會看到消息「請輸入的東西超過5位數的」

http://plnkr.co/edit/porkuq5JcKDU89s8g8ZT?p=preview

自定義驗證「greaterThanOne」是在做定義 - 某些指令。您可以通過添加一個name屬性,如myElementContainer顯示其消息:

<do-something name="myElementContainer" ng-model="myElement"></do-something> 
    <h4 data-ng-show="myForm.myElementContainer.$error.greaterThanOne">Please enter a value greater than 1</h4> 

我會推薦給定義在另一個指令邏輯爲輸入元素的屬性。

此外,使用$驗證,建議在調用$ setValidity: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController