针对twitter bootstrap form-group的AngularJS指令

Die*_*ego 5 angularjs angularjs-directive

我最近一直在玩角度,到目前为止一直很好,但我正在努力与指令.

我正在尝试创建一个指令,为一个标准的bootstrap表单组生成html标记及其相应的验证消息.

所以基本上我试图转换这个:

<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>
Run Code Online (Sandbox Code Playgroud)

进入这个:

<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>
Run Code Online (Sandbox Code Playgroud)

到目前为止,这就是我所拥有的:

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;
            });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

如果输入无效,这会正确设置引导类"has-error"到表单组.

现在我想添加验证消息,我找不到一种有效的方法.这就是我所拥有的:

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);
        }
    };
Run Code Online (Sandbox Code Playgroud)

formControlValidate.html:

<div class="controls" ng-transclude></div>
    <div data-ng-repeat="error in errors">
    <div class="label label-danger">
        {{error}}
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

但这不起作用.我在两个指令中随机更改参数,但无法弄清楚如何使其工作.

任何想法或改进将不胜感激.

谢谢!

Bet*_* St 9

更新:这是我的最新要点(角度1.3):https://gist.github.com/lpsBetty/3259e966947809465cbe


OLD解决方案:

我尝试过类似的东西,也许这个链接也可以帮助你:http://kazimanzurrashid.com/posts/create-angularjs-directives-to-remove-duplicate-codes-in-form

这是我的解决方案.我不知道为什么,但我不得不使用表格.$ dirty,不可能使用输入.$ dirty ..(我使用angular-translate)

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>
Run Code Online (Sandbox Code Playgroud)

指示:

  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;
        });
      }
    };
  });
Run Code Online (Sandbox Code Playgroud)