链接函数中的AngularJS$setValidity设置错误元素/表单的有效性。在单元测试中不可访问
我在指令的链接函数中设置表单的有效性,它在实践中起作用。然而,它似乎把验证器放在了错误的元素上,我无法在Jasmine单元测试中访问它。以下是我所做工作的精简版本: 该指令是嵌套表单的一部分,但我不认为这有什么区别:链接函数中的AngularJS$setValidity设置错误元素/表单的有效性。在单元测试中不可访问,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我在指令的链接函数中设置表单的有效性,它在实践中起作用。然而,它似乎把验证器放在了错误的元素上,我无法在Jasmine单元测试中访问它。以下是我所做工作的精简版本: 该指令是嵌套表单的一部分,但我不认为这有什么区别: // directive view <tfoot ng-form="formStep"> <tr> <td> <div test-directive ng-model="testDirecti
// directive view
<tfoot ng-form="formStep">
<tr>
<td>
<div test-directive ng-model="testDirective.model" ng-change="checkValidity()"></div>
</td>
</tr>
</tfoot>
在下面的部分指令中,验证程序以
<div class="testDirective">
而不是
<div ng-form="testDirectiveForm">
因此,当输入发生变化时,代码的最终结果是
<div class="testDirective ng-scope ng-isolate-scope ng-invalid-test-error ng-dirty ng-valid-parse">
(至少在从单元测试记录时。)
//test.directive.partial.html
选项1
在单元测试中,如果I console.log元素.isolateScope().testDirectiveForm.$error,则在未设置输入值的情况下,它包含required的错误。但是,它不包含testError的错误。它似乎被放在上面的元素上
// Unit test
describe('testDirective', function () {
var $scope;
beforeEach(angular.mock.module('app'));
beforeEach(inject(function($rootScope){
$scope = $rootScope.$new();
}));
describe('link function', function(){
var createElement, element, isolateScope;
beforeEach(inject(function($compile){
$scope.ngModel;
element = angular.element('<div test-directive></div>');
element.attr('ng-model', 'ngModel');
createElement = function(){
element = $compile(element)($scope);
};
}));
describe('after link', function () {
beforeEach(inject(function () {
createElement();
}));
describe('after initialization', function () {
beforeEach(function () {
$scope.$apply();
isolateScope = element.isolateScope();
});
it('.checkValidity should set the the error to testError', inject(function($rootScope){
isolateScope.checkValidity();
$rootScope.$digest();
console.log(isolateScope.testDirectiveForm.$error.testError);
expect(isolateScope.testDirectiveForm.$error.testError).toBeDefined();
}));
});
});
});
});
//单元测试
描述('testDirective',函数(){
var$范围;
每个之前(angular.mock.module('app'));
beforeach(注入(函数($rootScope){
$scope=$rootScope.$new();
}));
描述('link function',function(){
var createElement、element、isolateScope;
beforeach(注入(函数($compile){
$scope.ngModel;
元素=角度。元素(“”);
attr('ng-model','ngModel');
createElement=函数(){
元素=$compile(元素)($scope);
};
}));
描述('链接后',函数(){
beforeach(注入(函数)(){
createElement();
}));
描述('初始化后',函数(){
beforeach(函数(){
$scope.$apply();
isolateScope=元素。isolateScope();
});
它('.checkValidity应将错误设置为testError',inject(函数($rootScope){
isolateScope.checkValidity();
$rootScope.$digest();
log(isolateScope.testDirectiveForm.$error.testError);
expect(isolateScope.testDirectiveForm.$error.testError).TobedeDefined();
}));
});
});
});
});
这是怎么回事?我认为我在链接函数中得到的控制器属于该指令,但是如果我在测试中记录“element.scope()”,我就看不到验证器,也看不到任何检查它的方法。有更好的方法来解决这些问题吗?我通过从测试中的element.data()获取模型控制器来解决这个问题,如下所示:
// Unit test
describe('testDirective', function () {
var $scope, modelController;
beforeEach(angular.mock.module('app'));
beforeEach(inject(function($rootScope){
$scope = $rootScope.$new();
}));
describe('link function', function(){
var createElement, element, isolateScope;
beforeEach(inject(function($compile){
$scope.ngModel;
element = angular.element('<div test-directive></div>');
element.attr('ng-model', 'ngModel');
createElement = function(){
element = $compile(element)($scope);
};
}));
describe('after link', function () {
beforeEach(inject(function () {
createElement();
}));
describe('after initialization', function () {
beforeEach(function () {
$scope.$apply();
isolateScope = element.isolateScope();
modelController = element.data().$ngModelController;
});
it('.checkValidity should set the the error to testError', inject(function(){
isolateScope.checkValidity();
expect(modelController.$error.testError).toBeDefined();
}));
});
});
});
});
通过在链接函数中使用作用域将验证器放在testDirectiveForm上,我还能够访问隔离作用域上的表单,如下所示:
function checkValidity(){
scope.testDirectiveForm.$setValidity('testError', false);
}
这很容易通过我最初所做的工作进行单元测试:
it('.checkValidity should set the the error to testError', inject(function($rootScope){
isolateScope.checkValidity();
$rootScope.$digest();
console.log(isolateScope.testDirectiveForm.$error.testError);
expect(isolateScope.testDirectiveForm.$error.testError).toBeDefined();
}));
然而,它与项目中其他工作的完成方式并不一致
希望这些能帮助一些人。谢谢大家的回答。声明“我正在为表单获取ng模型控制器”没有意义。有一个for-each-form指令和一个for-each-input指令。为什么要为每个输入创建一个表单?此外,您不需要使用ng change来检查有效性。可以使用模型的对象controller@georgeawg在这种情况下,如何获取testDirectiveForm的控制器。我想从指令中访问它。@Wook先生,您能提供一个在这种情况下如何使用验证器的示例吗?它是单元可测试的吗?项目的一个要求是100%的代码覆盖率。实际上,我通过从element.data()获取控制器来解决这个问题
ngModelController.$validators.testError = function(modelValue, viewValue) {
if (!(viewValue && viewValue.length)) {
return false;
} else {
return true;
}
};
function checkValidity(){
scope.testDirectiveForm.$setValidity('testError', false);
}
it('.checkValidity should set the the error to testError', inject(function($rootScope){
isolateScope.checkValidity();
$rootScope.$digest();
console.log(isolateScope.testDirectiveForm.$error.testError);
expect(isolateScope.testDirectiveForm.$error.testError).toBeDefined();
}));