我在我的指令的链接功能中设置表单的有效性,它在实践中有效。但是,它似乎将验证器置于错误的元素上,而且我无法在Jasmine单元测试中访问它。这是我所做的精简版:
该指令是嵌套表单的一部分,但我不认为这会产生影响:
// directive view
<tfoot ng-form="formStep">
<tr>
<td>
<div test-directive ng-model="testDirective.model" ng-change="checkValidity()"></div>
</td>
</tr>
</tfoot>
在链接功能中,我获取了表单的modelController(或者它是指令的控制器?我不清楚这个。)
// directive linking function
(function () {
'use strict';
angular.module('app')
.directive('testDirective', testDirective);
testDirective.$inject = [];
function testDirective() {
return {
restrict : 'A',
require: 'ngModel',
scope : {
},
replace : true,
template: require('./test.directive.partial.html'),
link: function(scope, element, attributes, ngModelController){
scope.checkValidity = checkValidity;
function checkValidity(){
ngModelController.$setValidity('testError', false);
}
}
};
}
})();
在随后的指令部分中,验证器最终在
上<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
<div class="testDirective">
<div ng-form="testDirectiveForm">
<label class="radio-inline">
<input type="radio" ng-model="testModel.test" ng-value="true" required ng-change="checkValidity()" />
<strong>option 1</strong>
</label>
</div>
</div>
在单元测试中,如果我是console.log element.isolateScope()。testDirectiveForm。$ error,如果我没有为输入设置值,则包含所需的错误。但是,它不包含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();
}));
});
});
});
});
这里发生了什么?我认为我在链接函数中获得的控制器属于该指令,但是如果我记录了&#34; element.scope(),我无法看到验证器或看到任何方法来检查它。 &#34;在测试中。有没有更好的方法来解决这个问题?
答案 0 :(得分:0)
我通过在测试中从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();
}));
});
});
});
});
我尝试使用$ validators,它适用于我正在处理的其中一个组件(相同的单元测试有效)。但是,我正在处理的另一个组件每次更新视图时都无法运行验证程序。也许与嵌套表单控制器有关?代码是这样的:
ngModelController.$validators.testError = function(modelValue, viewValue) {
if (!(viewValue && viewValue.length)) {
return false;
} else {
return true;
}
};
我还可以通过在连接函数中使用范围将验证器放在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();
}));
但是,它并没有与项目中其他工作的完成方式保持一致。
希望其中一些可以帮助某人。谢谢大家的回答。