我应该如何打包插件函数以用于验证指令?

时间:2015-05-13 21:42:33

标签: javascript angularjs revealing-module-pattern

我正在制作以下验证指令,在this answer中向我建议:

MyBigAngularApp.directive("bkNgValidation", function ($compile) {
    return {
        priority: 10000,
        terminal: true,
        link: function (scope, element, attrs) {

            var validationType = attrs.bkNgValidation;
            window["addValidationFor_" + validationType](element);

            // prevent infinite loop
            element.removeAttr("bk-ng-validation");
            $compile(element)(scope);
        }
    };
});

然后,当我将此指令应用于html元素时,形式为bk-ng-validation="phoneNumber",我的指令调用此函数:

function addValidationFor_phoneNumber(element) {
    element.attr("ng-pattern", "/^[0-9]+$/");
    element.attr("ng-minlength", 5);
    element.attr("ng-maxlength", 8);
    alert("yeah baby");
}

addValidationFor_phoneNumber目前位于全局命名空间中,仅用于我的概念验证,但我希望使用一个揭示模块来组织可能成为许多验证功能的内容。或者我应该遵循一些其他模式,因为我在Angular内部工作?我怀疑我可以做一些事情,例如为揭示模块声明一个常数并将其注入指令中,但我想在问题走得太远之前我会问这个问题。

1 个答案:

答案 0 :(得分:0)

实际上,通常不建议在Javascript中使用全局范围中的变量,并且在使用AngularJS时使用绝对反模式。

您正在寻找的是service(或factory,它以相同的语法完成相同的工作),这将被注入您的指令。

MyBigAngularApp.service('bkService', function() {
  this.phoneNumber   = function(element) { ... }
  this.somethingElse = function(element) { ... }
});

你的指令变为:

// Note how bkService is injected to the directive in this first line
MyBigAngularApp.directive("bkNgValidation", function ($compile, bkService) {
  return {
    priority: 10000,
    terminal: true,
    link: function (scope, element, attrs) {

        var validationType = attrs.bkNgValidation;
        bkService[validationType](element);

        // prevent infinite loop
        element.removeAttr("bk-ng-validation");
        $compile(element)(scope);
    }
  };
});

现在,如果唯一将使用此服务的指令是那个,那么你真的不需要创建服务,但可以简单地将所有这些函数作为私有方法包装起来来自bkNgValidation:

MyBigAngularApp.directive("bkNgValidation", function ($compile) {

  var validations = {
    phoneNumber:   function(element) { ... }
    somethingElse: function(element) { ... }
  };

  return {
    priority: 10000,
    terminal: true,
    link: function (scope, element, attrs) {

        var validationType = attrs.bkNgValidation;
        validations[validationType](element);

        // prevent infinite loop
        element.removeAttr("bk-ng-validation");
        $compile(element)(scope);
    }
  };
});