2014-03-27 43 views
0

我想將輸入和一些標記包裝到AngularJS指令中。從AngularJS中的指令驗證字段

然而,這些字段被認爲總是被驗證,他們不應該這樣做。

請看看我的例子@http://plnkr.co/edit/TivmuqQI4Y5K56gwcadW

這裏是代碼爲那些誰不想看Plunker

我的指令

app.directive('myInput', function() { 
    return { 
    restrict: 'E', 
    require: '^ngModel', 
    templateUrl: 'form_control.html', 
    scope: { 
     label: '@', 
     placeholder: '@', 
     name: '@', 
     form: '=', 
     ngModel: '=ngModel' 
    }, 
    } 
}); 

這是我的模板

<div class="form-group" ng-class="{'has-error': form.{{name}}.$invalid && form.{{name}}.$dirty, 'has-success': form.{{name}}.$valid }"> 
<label for="{{name}}" class="col-sm-2 control-label">{{label}}</label> 
<div class="col-sm-10"> 
    <input type="{{type}}" class="form-control col-sm-10" id="{{name}}" name="{{name}}" ng-model="ngModel" placeholder="{{placeholder}}" ng-maxlength="10" ng-required="true"> 
</div> 
</div> 

這是在我的index.html

<my-input ng-model="website.url" name="url" label="URL" placeholder="http://example.com" form="form"></my-input> 

即使模板中的輸入是必需的,該字段也會被驗證,如果該字段爲空,則該字段不應爲空。

我在做什麼錯?

+0

在你的運動員,一個領域是綠色的,一個是紅色的。你想在加載時變綠嗎?那麼顯示無效時?何時提交表格?表單如何知道何時驗證輸入?任何必填字段在DOM加載時無效。 – SoEzPz

回答

0

必填字段在DOM負載上立即無效,因爲它們在有值之前無效。

此外,在您的運動員的頂部輸入是綠色的,有效的錯覺,而較低的輸入是紅色顯示無效,因爲它應該。

你不能做到這一點...

<div class="form-group" ng-class="{'has-error': form.{{name}}.$invalid && form.{{name}}.$dirty, 'has-success': form.{{name}}.$valid }"> 

的問題是與窗體名稱字段。當你這樣做......

<input type="{{type}}" class="form-control col-sm-10" id="{{name}}" name="{{name}}" ng-model="ngModel" placeholder="{{placeholder}}" ng-maxlength="10" ng-required="true"> 

名=「{{名}}實際上將編譯爲名稱:{{名}}形式對象〔實施例:

{{name}}: Constructor$dirty: false 
      $error: Object 
      $formatters: Array[1] 
      $invalid: true 
      $isEmpty: function (value) { 
      $modelValue: undefined 
      $name: "{{name}}" 
      $parsers: Array[1]... 

這張拍攝($ scope.form)並查看對象 under $ error你會發現有兩個輸入這個表單引用,它們都不是名爲'url'的預期輸入, ,他們實際上是'標題'輸入和您在這裏看到的指令輸入'{{name}}'...

form: Constructor 
    $addControl: function (control) { 
    $dirty: false 
    $error: Object... 
     $name: "title"... 
     $name: "{{name}}" 

這裏是我已經成立CONSOLE.LOG形式

Plunker

這表明,形式沒有任何「網址」輸入想法分叉plunker。爲了解決這個問題,您可以爲輸入名稱字段編寫自定義指令。或者只是使用我在下面寫的那個。

app.directive('myName', function(){ 

    var myNameError = "myName directive error: " 

    return { 
    restrict:'A', // Declares an Attributes Directive. 
    require: 'ngModel', // ngModelController. 

    link: function(scope, elem, attrs, ngModel){ 
     if(!ngModel){ return } // if no ngModel exists for this element 

     checkInputFormat(attrs); // check myName input for proper formatting. 

     var inputName = attrs.myName.match('^\\w+').pop(); // match upto '/' 
     assignInputNameToInputModel(inputName, ngModel); 

     var formName = attrs.myName.match('\\w+$').pop(); // match after '/' 
     findForm(formName, ngModel, scope); 
    } // end link 
    } // end return 

    function checkInputFormat(attrs){ 
    if(!/\w\/\w/.test(attrs.myName)){ // should be in format "wordcharacters/wordcharacters" 
     throw myNameError + "Formatting should be \"inputName/formName\" but is " + attrs.myName 
    } 
    } 

    function assignInputNameToInputModel(inputName, ngModel){ 
    ngModel.$name = inputName // adds string to ngModel.$name variable. 
    } 

    function addInputNameToForm(formName, ngModel, scope){ 
    scope[formName][ngModel.$name] = ngModel; return // add input name and input object. 
    } 

    function findForm(formName, ngModel, scope){ 
    if(!scope){ // ran out of scope before finding scope[formName] 
     throw myNameError + "<Form name=" + formName + "'> element could not be found." 
    } 
    if(formName in scope){ // found scope[formName] 
     addInputNameToForm(formName, ngModel, scope) 
     return 
    } 
    findForm(formName, ngModel, scope.$parent) // recursively search through $parent scopes 
    } 
}); 

// DIRECTIVE NOTES: 
// This directive is used by simply including the following HTML element: 
// <input my-name="email/profileForm">. 
// In the example above, the input name is "email" and the form name 
// that this input would be attached to would be named "profileForm" 
// Like this... 
// <form name="profileForm"> 
// <input my-name="email/profileForm"> 
// </form> 
// Notice this "/" dividing the input name from the form name. This directive uses the '/' 
// to separate the input name from the form name. 
// Although it has not been tested yet, this directive should work with multi nested forms 
// as well, as the recursive search only looks for the form name that was passed in, inwhich 
// to bind the ngModel to. 
// In this example, other form names would be skipped. 
// <form name="profileForm"> 
// <form name="miniFormOne"> 
//  <form name="miniFormTwo"> 
//  <input my-name="email/profileForm"> 
//  </form> 
// </form> 
// </form> 
// The above example may not be the best behavior, but was just added as an example. 

本指令,你可以使用這樣的

<input type="{{type}}" class="form-control col-sm-10" id="{{name}}" my-name="{{ variableName + '/' + yourformnamevariable }}" ng-model="ngModel" placeholder="{{placeholder}}" ng-maxlength="10" ng-required="true"> 

的MYNAME指令的嵌套指令輸入會得到這樣的:你的情況「URL /表」,那麼它會添加$ name這個變量將成爲'輸入'的ngModel'url',以及搜索名爲「form」的表單的範圍,並將ndModel附加到THAT表單中。該指令使用'/'來分隔名稱。搜索是遞歸的,並且將一直移動,直到找到表單名稱或帶有消息的錯誤。

當然,當你創建動態的輸入名字,你怎麼召喚出

formName.dynamicInputName。$有效嗎?因爲您不知道動態輸入名稱是什麼!

因此,使用形式。{{名}} $無效& &形式。{{名}}。$髒不,除非你做這個工作...

form.$valid && form.$dirty 

但贏得」 t爲每個單獨的輸入工作。你可以找出你自己的方式做到這一點...

我用另一種指令輸入

然後在我的-錯誤,我只是聽ngModel例如需要ngModel之後裏面,你現在可以調用ngModel。 $ invalid然後設置一個變量來改變CSS。如果我有一些時間,我會製作一個jsFiddle並將其鏈接到底部。但是,您可以使用類input.ng-invalid {border-color:red; }並且輸入將是紅色的,直到它們有效。

如果這不能解決問題,請提出一些問題...我們會得到它。

希望這個幫助的