从ng条消息中提取ng条消息密钥

Extract ng-message key from ng-messages

本文关键字:消息 ng 密钥 提取      更新时间:2023-09-26

我需要创建一个指令myDirective,它读取其中的所有ng消息键,并且它仍然创建一个有效的ng消息元素:

指令模板:

<div id="myDirective">
  <div ng-messages="myform.$error" ng-transclude></div>
</div>

用法:

<my-directive>
  <div ng-message="required">something is required</div>
  <div ng-message="custom">custom validation</div>
</my-directive>

所以在这种情况下,我想得到一个"必需"answers"自定义"的数组。问题是我无法做到这一点,因为当我的指令进入它自己的链接函数时,所有的ng message元素都已经被隐藏(更准确地说,是从DOM中删除的)。如何绕过这个?

指令的内容在编译阶段被删除,因为您的指令有transclude: true(我假设是这样,因为您使用的是ng-transclude)。

在这种情况下,内容可以通过传入的transclude函数获得(这实际上是ng-transclude在封面下使用的)。

transclude函数是link(或预链接)函数的第5个参数:

link: function(scope, element, attrs, ctrls, transclude){
  var transcludedContents; // jqLite of the contents
  transclude(function(clone){
    transcludedContents = clone;
  });
  // do whatever you do to extract ng-message values from transcludedContents
  // just remember, that it could also come in the form:
  // <ng-message when="required"> and 
  // <div ng-message-exp="errorMessage.type">
}

我们当中懒惰的人可能不想处理DOM计数,因此您可以为ng-message指令创建另一个处理程序,该处理程序与您的my-directive交互以注册自己:

.directive("myDirective", function() {
  return {
    transclude: true,
    templateUrl: "myDirective.template.html",
    controller: function() {
      var messages = [];
      this.registerNgMessage = function(val) {
        messages.push(val);
      };
    }
  };
})
.directive("ngMessage", complementaryNgMessageDirective)
.directive("ngMessageExp", complementaryNgMessageDirective);
function complementaryNgMessageDirective() {
  return {
    priority: 10, // must be higher than ngMessage, because ngMessage is terminal
    require: "^?myDirective", // must be optional not to break existing code
    link: function(scope, element, attrs, myDirectiveCtrl) {
      if (!myDirectiveCtrl) return; // do nothing, if not paired with myDirective
      var staticExp = attrs.ngMessage || attrs.when;
      var dynamicExp = attrs.ngMessageExp || attrs.whenExp;
      var val;
      if (dynamicExp) {
        val = scope.$eval(dynamicExp);
      } else {
        val = staticExp;
      }
      myDirectiveCtrl.registerNgMessage(val);
    }
  };
}