【问题标题】:How should I package plugin functions for use in a validation directive?我应该如何打包插件函数以在验证指令中使用?
【发布时间】:2015-05-13 21:42:32
【问题描述】:

我正在研究以下验证指令,在 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 内部工作,所以我应该遵循其他一些模式?我怀疑我可以做一些事情,比如为显示模块声明一个常量并将其注入指令中,但我想在走错路之前先问这个问题。

【问题讨论】:

    标签: javascript angularjs revealing-module-pattern


    【解决方案1】:

    确实,一般不建议在 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);
        }
      };
    });
    

    【讨论】:

    • 谢谢,一个菜鸟的好答案(我,不是你)。我真的很喜欢服务理念,将元素链接到功能(即指令)和实现该功能(即服务)的关注点分开,但就目前而言,仅这一次,我将使用私有方法方法,限制我涉足角度空间。
    • 是的,只要您至少需要在两个指令之间共享信息,服务就会变得非常有用。但是,如果它们具有很强的层次结构(即 dir2 始终在 dir1 中),则需要优先使用一些绑定或继承方法,如果您继续使用那个伟大的框架,您以后可能会遇到这些情况:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    相关资源
    最近更新 更多