【问题标题】:Angular directive wrapping ng-messagesAngular 指令包装 ng-messages
【发布时间】:2015-09-15 11:31:59
【问题描述】:

我创建了一个角度指令来处理错误消息的显示。它包装了内置指令 ng-messages 和 ng-message-exp。 (这样做的原因是为了创建一个自定义的弹出框错误消息控件)

为了实现这一点,我创建了一个跟踪错误消息的父控制器。它包含一个控制器,该控制器具有添加消息的方法,该方法从子指令中调用。

当我指定表单 ng-messages=\"myForm.myEmail.$error\" role=\"alert\" ng-show=\"myForm.myEmail.$invalid && myForm.myEmail.$dirty\"在 popoutValidation 指令的指令模板中的根元素上。 IE。对其进行硬编码,使其映射到页面上的表单和元素,它可以正常工作并正确显示所需或无效电子邮件的错误消息。但是,当我尝试动态传递表单名称和相关控件时,它会停止工作。有什么想法可以实现这一目标吗?

<ng-form name="myForm">
      <input type="email" name="myEmail2" ng-model="vm.name" required />
      <popout-validation position="left" form="myForm" for="myEmail2">
          <popout-validation-message type="required" message="This is requireddddd." />
         <popout-validation-message type="email" message="invalid email address." />
      </popout-validation>

   </ng-form>

还有如下代码:

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

app.controller("myCtrl", function() {
   var vm = this;
   vm.name = "ee";
});

app.directive("popoutValidationMessage", function() {
   return {
      scope: {
         type: "@",
         message : "@"
      },

      require: "^popoutValidation",
      replace: true,
      link: function(scope, element, attr, ctrl) {
         ctrl.addMessage(attr.type, attr.message);
      }
   }
});

app.directive("popoutValidation", function() {
   return {
      require: "^form",
      replace: true,
      transclude: true,
      template: "<div class=\"error\" ng-messages>" +
         "<div ng-repeat=\"errorMessage in errorMessages\">" +
         "<div ng-message-exp=\"errorMessage.type\">{{ errorMessage.text }}</div>" +
         "</div>" +
         "<div ng-transclude></div>" +
         "</div>",
      compile: function(element, attr) {
         //ng-messages=\"myForm.myEmail.$error\" role=\"alert\" ng-show=\"myForm.myEmail.$invalid && myForm.myEmail.$dirty\"

         var formStr = attr.form + "." + attr.for;
         element.attr("ng-messages", formStr + "." + "$error");
         element.attr("ng-show", formStr + "." + "$invalid && " + formStr + "." + "$dirty");


      },
      controller: function($scope) {
         $scope.errorMessages = [];

         this.addMessage = function(type, message) {
            $scope.errorMessages.push({
               type: type,
               text: message
            });
         };
      }
   }
});

http://codepen.io/mantisimo/pen/ojbqoa?editors=101

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    可能有两种方法可以使用指令处理错误消息。

    1. 使用 $rootScope。当指令模板设置变量如 {{$root.msg}} 时,可以在控制器中设置 $rootScope.msg。当然,$rootScope 中的变量可以在指令中渲染。
    2. 更好的做法是没有范围污染。那么这条路来了。首先创建这样的指令。
    app.directive("toasterContainer", function($timeout, $compile, $sce, toaster) {
        return {
            replace: true,
            restrict: "E",
            scope: true,
            link: function(scope, elem, attrs) {
                scope.$on('toaster-newToast', function() {
                    scope.toast = toaster.toast;
                    $timeout(function() {
                        toaster.toast.display = false;
                    }, toaster.toast.timeout);
                });
            },
            templateUrl: "/static/shop/snippets/toaster_container.html"
        }
    });
    

    然后像toaster这样创建服务。

    define([], function() {
        var toaster = function($timeout, $rootScope) {
            this.pop = function(type, msg, timeout) {
                var type = (typeof type === "undefined") ? "info" : type;
                var msg = (typeof msg === "undefined") ? "" : msg;
                var timeout = (typeof timeout === "undefined") ? 5000 : timeout;
                this.toast = {
                    type: type,
                    msg: msg,
                    timeout: timeout,
                    display: true
                }
                $rootScope.$broadcast('toaster-newToast');
            },
            this.initPop = function(type, msg, timeout) {
                var scope = this;
                $timeout(function() {
                    scope.pop(type, msg, timeout);
                }, 300);
            }
        }
        toaster.$inject = ['$timeout', '$rootScope'];
        return toaster;
    })
    

    然后在控制器中,您可以简单地使用toaster 服务来弹出这样的错误消息。

    toaster.pop("success", msg);
    

    【讨论】:

    • 感谢您的建议...我正在寻找对上述代码的修复。干杯
    【解决方案2】:

    已修复.... 只需要编译结果

    compile: function(element, attr) {
    
             var formStr = attr.form + "." + attr.field;
             element.attr("ng-messages", formStr + "." + "$error");
             element.attr("ng-show", formStr + "." + "$invalid && " + formStr + "." + "$dirty");
    
             return {
                post : function(scope, element, attr, ctrl, transclude) {
                   $compile(element)(scope);
                }
             }
          }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-07
      • 2013-04-11
      • 2015-01-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多