AngularJS - 创建一个添加兄弟元素的指令

时间:2013-06-05 14:20:14

标签: angularjs angularjs-directive

我正在创建一个看起来像这样的my-validate指令

<input my-validate="customValidation" ng-model="model" />

我想要做的是将一个sybling元素附加到指令,就像这样

错误模板:

<ul class"errors">
   <li ng-repeat="for error in errors">{{error}} not valid</li>
</ul> 

errors在指令范围内定义。

我在compile函数中添加了错误模板,但我遇到的问题是链接函数中的scope与附加的模板不同。

以下是一个说明问题的插件:http://plnkr.co/edit/ghdtdYruQaaO0Yxxlrt1?p=preview

'world'在指令模板中可见,但不在添加的元素上:S。

3 个答案:

答案 0 :(得分:6)

那是因为你的div“2 hello”在你的范围可见的容器之外。 您可以使用element.append()代替element.after()来使范围可用。

指令

var app = angular.module('plunker', []);


app.directive('myValidate', function($compile) {
      return {
        template: '<span>1. Hello {{world}}  my scope is {{$id}} (parent: {{$parent.$id}})<span/>',
        replace: true,
        restrict: 'A',
        scope: true,
        compile: function (element) {

          element.append('<div>2. Hello {{ world }}, my scope is {{$id}} (parent: {{$parent.$id}})</div>');

          return function(scope) {
            scope.world = 'World';
            //$compile()(scope);
          };
        }
      };
});

HTML

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script data-require="angular.js@1.1.5" data-semver="1.1.5" src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="app.js"></script>
  </head>

  <body>
    <input my-validate="" />
  </body>

</html>

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

答案 1 :(得分:1)

我正在阅读并检查示例,因为我在相同的情况下显示验证消息,但输入字段下,消息可以根据需要的验证类型而改变。

所以我提出了这个解决方案

var app = angular.module('app', []);

app.controller('ctrl', function($scope, CONSTANTS) {
  $scope.title = "title";
  $scope.CONSTANTS = CONSTANTS;
});

app.constant('CONSTANTS', {
  LENGHT_1: 3,
  LENGHT_2: 4
});

app.directive('dir', function($compile) {
  return {
    scope: true,
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, elem, attrs, ngModel) {
      scope.maxLength = false;
      scope.required = false;
      scope.max = scope.$eval(attrs['ngMaxlength']);
      var tpl = '<div ng-if="maxLength" ng-include="\'length.tpl.html\'"></div>' +
        '<div ng-if="required" ng-include="\'required.tpl.html\'"></div>';
      var el = $compile(tpl)(scope);
      elem.after(el);

      scope.$watch(attrs['ngModel'], function(newValue, oldValue, scope) {
        if (ngModel.$error !== null && ngModel.$error.maxlength) {
          scope.maxLength = true;
        } else {
          scope.maxLength = false;
        }

        if (ngModel.$error !== null && ngModel.$error.required && ngModel.$dirty) {
          scope.required = true;
        } else {
          scope.required = false;
        }
      });
    }
  }
});
<!DOCTYPE html>
<html ng-app="app">

<head>
  <script data-require="angular.js@1.4.7" data-semver="1.4.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
  
  <script type="text/ng-template" id="length.tpl.html">
    max length {{max}}
  </script>
  <script type="text/ng-template" id="required.tpl.html">
    required
  </script>
</head>

<body ng-controller="ctrl">
  <h1>Input Validation</h1> {{title}}
  <br><br>
  <form name="form" novalidate>
    <input dir name="input_one" ng-model="bar" ng-maxlength="CONSTANTS.LENGHT_1" required>
    <br>
    input one: {{form.input_one.$error}}
    <br>
    <br>
    <input dir name="input_two" ng-model="foo" ng-maxlength="CONSTANTS.LENGHT_2">
  </form>
  <br>
  input two: {{form.input_two.$error}}
</body>

</html>

On Plunkr

希望它有所帮助。

答案 2 :(得分:-1)

我认为您通过使用表单错误切换显示来处于正确的轨道上。这正是标准Angular文档中推荐的方式。

但是,如果您想为单个输入显示多个错误,甚至可能从那里控制错误消息,我建议使用服务,例如在http://plnkr.co/edit/iNcNs2ErrOnYf9I7whdu?p=preview实施。

现在,每个令牌可以有一条消息,但每个输入可以有多个令牌。如果你想为每个标记多个消息,只需使用一个消息数组而不是单个字符串值(注意,unset在该方法中会变得更复杂)。

希望有所帮助, 亚历