angularjs - 如何正确应用范围以便顺序无关紧要

标签 angularjs unit-testing jasmine

我正在尝试为将值与其他输入字段匹配的指令编写单元测试。问题是如果我在应用指令的元素之前定义要匹配的元素,它可以正常工作,否则会失败。

当模板是时它工作正常

tpl = '<input name="verifyNewPassword" ng-model="verifyNewPassword" type="password"/>';
tpl += '<input name="newPassword" ng-model="newPassword" type="password" equals-to="userForm.verifyNewPassword"/>';

当模板为
tpl = '<input name="newPassword" ng-model="newPassword" type="password" equals-to="userForm.verifyNewPassword"/>';
tpl+='<input name="verifyNewPassword" ng-model="verifyNewPassword" type="password"/>';

这是我的指令
.directive('equalsTo', function() {
    return {
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
            var sc = scope;
            scope.$watch(attrs.ngModel, function() {
                var eqCtrl = scope.$eval(attrs.equalsTo);
                console.log('Value1: ' + ctrl.$viewValue + ', Value2: ' + eqCtrl.$viewValue);
                if (ctrl.$viewValue===eqCtrl.$viewValue || (!!!ctrl.$viewValue && !!!eqCtrl.$viewValue)) {
                    ctrl.$setValidity('equalsTo', true);
                    eqCtrl.$setValidity('equalsTo', true);
                } else {
                    ctrl.$setValidity('equalsTo', false);
                    eqCtrl.$setValidity('equalsTo', false);
                }
            });
        }
    };
})

这是我的测试代码:
describe('Unit: Testing Directives', function() {
    var elm, scope;

    beforeEach(function() {
        module('mctApp');

        inject(function($rootScope, $compile) {
            scope = $rootScope.$new();
        });
    });

    function compileDirective(tpl) {
        if(!tpl) {
            tpl = '<input name="newPassword" ng-model="newPassword" type="password" equals-to="userForm.verifyNewPassword"/>';
            tpl += '<input name="verifyNewPassword" ng-model="verifyNewPassword" type="password"/>';            
        }
        tpl = '<form name="userForm">' + tpl + '</form>';

        inject(function($compile) {
            var form = $compile(tpl)(scope);
        });

        scope.$digest();

    }

    it('must be valid form as both values are equal', function() {
        scope.newPassword = 'abcdef';
        scope.verifyNewPassword = 'abcdef';
        compileDirective();                 
        expect(scope.userForm.$valid).toBeTruthy();
    });
});

最佳答案

测试失败,因为当 watch最初触发时,$viewValueequals-to ngModelController 为 NaN,因此字段有效性设置为 false 并且表单无效。

http://plnkr.co/edit/OZVmogR6GT2pIKUrHpuX?p=preview

当您在观察范围内输入的对象时 ngModel分配给 - 已经设置为“abcdef” - watch 只被调用一次。如果您观看 ngModel.$viewValue与您比较的输入相反,它保证初始状态始终是正确的,无论 DOM 中的输入顺序如何。

我还认为,观察该值更有意义,因为它是您要比较的值。

.directive('equalsTo', function() {
    return {
        require: 'ngModel',
        link: function(scope, elm, attrs, ctrl) {
            var sc = scope;
            scope.$watch(attrs.equalsTo + '.$viewValue', function() {
                var eqCtrl = scope.$eval(attrs.equalsTo);
                console.log('Value1: ' + ctrl.$viewValue + ', Value2: ' + eqCtrl.$viewValue);
                if (ctrl.$viewValue===eqCtrl.$viewValue || (!!!ctrl.$viewValue && !!!eqCtrl.$viewValue)) {
                    ctrl.$setValidity('equalsTo', true);
                    eqCtrl.$setValidity('equalsTo', true);
                } else {
                    ctrl.$setValidity('equalsTo', false);
                    eqCtrl.$setValidity('equalsTo', false);
                }
            });
        }
    };
})

http://plnkr.co/edit/OZVmogR6GT2pIKUrHpuX?p=preview

备注

如果您使用的是 angular 1.3+,那么可能值得将新的验证器管道视为解决同一问题的更优雅的方法。

关于angularjs - 如何正确应用范围以便顺序无关紧要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27546095/

相关文章:

javascript - 从键值结构中获取数据并将其与 AngularJS 中的 ng-repeat 中的值进行比较

html - 使用自定义 css 修改 ng-grid 复选框,修改空间

python - 在 Python 中使用 Angular JS( Protractor )和 Selenium

javascript - AngularJs ng-href 动态链接的范围未更新/工作

ios - 使用iOS中的OCUnit在XCode 4.5中使用Core Data对象进行单元测试

javascript - 如何在 Jasmine 中测试 JavaScript 图像 onerror 回调?

python - 假设+单元测试测试锁定sqlite数据库

android - Kotlin android 应用程序 ExampleInstrumentedTest 不工作

javascript - jasmine-jQuery,如何测试表单填写和 HTML 元素的更改?

npm - 我怎样才能在 Jasmine 记者生成的报告中加上标志?