2014-03-24 15 views
5

Ich habe in letzter Zeit mit eckigen gespielt, so weit so gut, aber ich kämpfe mit Direktiven.AngularJS Direktive für Twitter Bootstrap Form-Gruppe

Ich versuche, eine Direktive zu erstellen, die die HTML-Markierung für eine Standard-Bootstrap-Formulargruppe mit den entsprechenden Validierungsnachrichten generiert.

Also im Grunde Ich versuche, diese zu konvertieren:

<form-group label="Password"> 
     <input type="password" data-ng-model="vm.password" name="password" id="password" class="form-control form-control-validate" 
       required data-ng-minlength="6" 
       data-required-error="Password is required" data-minlength-error="Your password must have at least 6 characters" /> 
</form-group> 

in diese:

<div class="form-group" data-ng-class="{'has-error': invalid}"> 
     <label for="password" class="col-md-2 control-label">Password</label> 
     <div class="col-md-10"> 
      <input data-ng-model="vm.password" type="password" id="password" name="password" class="form-control" 
        required data-ng-minlength="6"/> 
      <div data-ng-show="changePasswordForm.$dirty && changePasswordForm.oldPassword.$invalid"> 
       <label data-ng-show="changePasswordForm.oldPassword.$error.required" class="label label-danger"> 
        Password is required 
        <br /> 
       </label> 
       <label data-ng-show="changePasswordForm.oldPassword.$error.minlength" class="label label-danger"> 
        Your password must have at least 6 characters 
       </label> 
      </div> 
     </div> 
</div> 

Bisher ist das, was ich habe:

app.directive('formGroup', function() { 
    return { 
     templateUrl: 'app/directives/formGroup.html', 
     restrict: 'E', 
     replace: true, 
     transclude: true, 
     require: "^form", 
     scope: { 
      label: "@", 
     }, 
     link: function (scope, element, attrs, formController) { 
      var input = element.find(":input"); 
      var id = input.attr("id"); 
      scope.for = id; 
      var inputName = input.attr("name"); 
      // Build the scope expression that contains the validation status. 
      // e.g. "form.example.$invalid" 
      var inputInvalid = [formController.$name, inputName, "$invalid"].join("."); 
      scope.$parent.$watch(inputInvalid, function (invalid) { 
       scope.invalid = invalid; 
      }); 
     } 
    }; 
}); 

formGroup.html:

<div class="form-group" ng-class="{ 'has-error': invalid }"> 
    <label class="col-md-2 control-label" for="{{for}}">{{label}}</label> 
    <div class="col-md-10"> 
     <div data-ng-transclude=""></div> 
    </div> 
</div> 

Dies legt die Bootstrap-Klasse "has-error" korrekt auf die Formulargruppe fest, wenn die Eingabe ungültig ist.

Jetzt möchte ich Validierungsnachrichten hinzufügen, und ich konnte keinen Weg finden, der funktioniert. Das ist, was ich habe:

app.directive('formControlValidate', function() { 
    return { 
     templateUrl: "app/directives/formControlValidate.html", 
     restrict: 'C', 
     require: ["^form", "ngModel"], 
     scope: { }, 
     transclude: true, 
     //replace: true, 
     link: function (scope, element, attrs, controls) { 
      var form = controls[0]; 
      var inputName = attrs.name; 
      var inputErrors = [form.$name, inputName, "$error"].join("."); 
      scope.$parent.$watch(inputErrors, function (newValue) { 
       if (newValue) { 
        scope.errors = []; 
        angular.forEach(newValue, function (value, key) { 
         var error = attrs[key + 'Error']; 
         if (value && error) { 
          scope.errors.push(error); 
         } 
        }); 
       } 
      }, true); 
     } 
    }; 

formControlValidate.html:

<div class="controls" ng-transclude></div> 
    <div data-ng-repeat="error in errors"> 
    <div class="label label-danger"> 
     {{error}} 
    </div> 
</div> 

Aber das funktioniert nicht. Ich ändere zufällig Parameter in beiden Direktiven, aber ich kann nicht herausfinden, wie es funktioniert.

Alle Ideen oder Verbesserungen würden sehr geschätzt werden.

Danke!

+0

Könnten Sie dies in Plunkr oder etwas bringen? – bjtitus

Antwort

9

UPDATE: dies ist meine letzte Kern (Winkel 1.3): https://gist.github.com/lpsBetty/3259e966947809465cbe


OLD Lösung:

Ich habe versucht, etwas ähnlich, vielleicht diesen Link können Sie auch helfen: http://kazimanzurrashid.com/posts/create-angularjs-directives-to-remove-duplicate-codes-in-form

Das war meine Lösung. Ich weiß nicht, warum, aber ich hatte Formular verwenden $ schmutzig, war es nicht möglich Eingabe verwenden $ schmutzig .. (und ich verwende Winkel übersetzen)

HTML:..

<form-group input="form.password"> 
    <input type="password" class="form-control" placeholder="{{ 'user.password' | translate }}" required 
      name="password" ng-model="user.password" /> 
</form-group> 

Richtlinie:

app.directive('formGroup', function ($parse) { 
    return { 
     restrict: 'E', 
     require: '^form', 
     transclude: true, 
     replace: true, 
     scope: { 
     cssClass: '@class', 
     input: '=' 
     }, 
     template: '<div class="form-group" ng-class="{\'has-error\':hasError, cssClass:true}">'+ 
        '<div ng-transclude></div>' + 
        '<div ng-show="hasError">' + 
        '<span ng-repeat="(key,error) in input.$error" class="help-block"' + 
          'ng-show="input.$error[key]">{{\'form.invalid.\'+key | translate}}</span>' + 
        '</div>' + 
       '</div>', 
     link: function (scope, element, attrs, ctrl) { 
     var form = ctrl; 
     var input = attrs.input; 

     scope.$parent.$watch(input+'.$invalid', function (hasError) { 
      scope.hasError = hasError && form.$dirty; 
     }); 
     } 
    }; 
    }); 
+0

Danke! sieht gut aus. – Diego

+0

FWIW Ich konnte das Problem '$ dirty' lösen, indem ich die Callback-Funktion in 'function (hasError, _, parentScope) änderte {scope.hasError = hasError && parentScope. $ Eval (attrs.input). $ Dirty; } 'Es könnte jedoch einen einfacheren Weg geben. –

+0

Ich habe ein Gist für eckige 1.3 erstellt: https: //gist.github.com/lpsBetty/3259e966947809465cbe –