试图弄清楚指令是如何工作的,为它设计一个测试

时间:2015-07-12 06:14:05

标签: angularjs

我正在使用Jasmine + Karma并且需要找到一种方法来测试用于在密码不匹配时警告用户的角度指令 - 它似乎通过呈现true或false的指令来完成此操作,并且使用ngShow时显示的HTML以及其他几个属性是真的。

这是指令。我很难理解它是如何工作的。

app.directive('passwordMatch', [function () {
    return {
        restrict: 'A',
        scope:true,
        require: 'ngModel',
        link: function (scope, elem, attrs, control) {
            var checker = function () {
                var e1 = scope.$eval(attrs.ngModel);
                var e2 = scope.$eval(attrs.passwordMatch);
                if(e2!=null)
                return e1 == e2;
            };
            scope.$watch(checker, function (n) {
                control.$setValidity("passwordNoMatch", n);
            });
        }
    };
}]);

<small class="errorMessage" data-ng-show="signupForm.password2.$dirty && signupForm.password2.$error.passwordNoMatch && !signupForm.password2.$error.required"> Password do not match.</small>

据我所知,正在发生的是范围。$ watch正在观察更改的检查函数,然后将其放入侦听器参数并更新DOM上的属性?

如何做到这一点,然后当目的是检测密码是否不匹配时 - 如果它们不匹配,那么e1 === e2为假,并且该值被传递到$scope.watch(checker, function(n)...?如果它是如何工作的,那么它不会将值passwordNoMatch设置为false,这会使ng-show隐藏吗?

或者这不是它的工作方式,它是另一种方式吗?

在此之前,链接发生了什么:功能部分?

范围来自哪里(它只是在指令中说scope:true?) 和元素?还有attr(来自html元素的属性?)?

角度只是查看每个列表,元素和属性以及范围吗?某种程度上是否已存在passwordMatch属性?

$eval在做什么?

1 个答案:

答案 0 :(得分:0)

你在这里有很多问题,花一些时间使用Angular文档可以帮助你回答很多问题。我将链接到相关文档,以便您可以获得更全面的解释。

因此,据我所知,正在发生的事情是范围。$ watch正在观察更改的检查函数,然后将其放入侦听器参数并更新DOM上的属性?它是如何做到的?

我想你差不多了。当你观察一个函数时,它会在每个摘要周期被调用,如果函数的返回值发生了变化,那么它会调用你作为第二个参数传递的函数,即

function(n){
    control.$setValidity("passwordNoMatch", n);
}

要了解此功能,您需要了解require选项的作用。您已将require设置为'ngModel',基本上这意味着作为链接函数的第4个参数传入的control变量是对NgModelController的引用,它为ngModel指令提供API

$setValidity("passwordNoMatch", n)位将$error对象上的属性'passwordNoMatch'的值设置为n的值。因此,n这里是您正在观看的函数的返回值,而$error对象是FormController的一个属性,该属性在所有angular forms上都有名称HTML表单标记中定义的属性。所以,基本上这个函数设置了你在signupForm.password2.$error.passwordNoMatch标签中看到的<small>的值。

范围来自哪里(它只是说明范围:指令中是真的吗?)

链接功能的范围是(来自Angular docs)..

  

指令用于注册手表的范围。

scope: true位告诉Angular是否为该指令创建一个新的作用域,或者创建一个“原型继承自父作用域”的“隔离作用域”。如果你真的想要修改指令,我建议你花一些时间阅读directive definition object

$ eval在做什么?

传递给范围的第一个参数。$ eval作为Angular Expression执行,并返回结果。因此,在您的代码中,我怀疑他们都会从您的密码字段返回字符串,然后检查它们是否匹配。

希望有所帮助。