我正在实现一个简单的指令,它表示一个表单字段及其所有附加内容,如label,error field,regex都在一行中。
该指令如下:
<div ng-controller="parentController">
{{username}}
<!-- the directive -- >
<form-field label="Username:" regex="someRegex" constrainsViolationMessage="someValidationMessage" model="username" place-holder="some input value">
</form-field>
</div>
现在,我想测试指令范围和父范围之间的数据绑定。
测试是:
it("should bind input field to the scope variable provided by parent scope ! ", function () {
var formInput = ele.find('.form-input');
formInput.val("some input");
expect(ele.find('p').text()).toEqual('some input');
});
这个问题是我不知道为什么测试不通过,即使指令正常工作。 Here is a fiddle of the directive.
这是整个测试和测试设置。
var formsModule = angular.module('forms', []);
formsModule.controller('parentController', function ($scope) {
});
formsModule.directive('formField', function () {
var label;
var constrainsViolationMessage;
var placeHolder;
var model;
return {
restrict:'E',
transclude:true,
replace:false,
scope:{
model:'='
},
link:function (scope, element, attr) {
console.log("link function is executed .... ");
scope.$watch('formInput', function (newValue, oldValue) {
console.log("watch function is executed .... !")
scope.model = newValue;
});
scope.label = attr.label;
},
template:'<div class="control-group ">' +
'<div class="form-label control-label">{{label}}</div> ' +
'<div class="controls controls-row"> ' +
'<input type="text" size="15" class="form-input input-medium" ng-model="formInput" placeholder="{{placeHolder}}">' +
'<label class="error" ng-show={{hasViolationConstrain}}>{{constrainsViolationMessage}}</label>' +
'</div>'
}
});
beforeEach(module('forms'));
var ele;
var linkingFunction;
var elementBody;
var scope;
var text = "";
var placeHolder = "filed place holder";
var label = "someLabel";
var regex = "^[a-z]{5}$";
beforeEach(inject(function ($compile, $rootScope) {
scope = $rootScope;
elementBody = angular.element('<div ng-controller="parentController">' +
'<p>{{username}}</p>' +
'<form-field label="Username:" regex="someRegex" constrainsViolationMessage="someValidationMessage" model="username" place-holder="some input value"> </form-field>');
ele = $compile(elementBody)(scope);
scope.$digest();
}
));
afterEach(function () {
scope.$destroy();
});
iit("should bind input field to the scope variable provided by parent scope ! ", function () {
var formInput = ele.find('.form-input');
formInput.val("some input");
expect(ele.find('p').text()).toEqual('some input');
});
如您所见,我想声明表单输入反映在父作用域提供的“model”属性中设置的作用域变量中。
我在这里遗漏了什么吗? 谢谢你帮助我......!
答案 0 :(得分:28)
设置输入值后,您错过了scope.$apply()
调用,因此更改永远不会被消化。在常规应用程序生命周期中,这将自动发生,但您必须在测试中手动触发此操作
看一下https://github.com/angular/angular.js/blob/master/test/ng/directive/formSpec.js的大量例子。
答案 1 :(得分:7)
在添加条件后使用$ scope。$ digest()来执行watch。它会消防手表。