我已经创建了一个编辑指令,用于将html输入包装在一个花哨的框架中。
现在我正在创建一个单元测试来检查一旦输入输入,就会设置表单控制器的脏状态。
我正在使用jQuery.trigger()来模拟这个,但我什么都没得到......
var input = $('input');
var e = $.Event('keydown');
e.which = 'x'.charCodeAt(0);
e.keyCode = 'x'.charCodeAt(0);
input[0].focus();
input.trigger(e);
我有一个羽毛here
我做错了什么?
谢谢!
答案 0 :(得分:5)
从answer到类似的问题:
你所犯的错误就是你对jQuery的期待 触发方法。如果你查看代码,你会看到什么 它正在实际执行jQuery注册的事件处理程序 不是DOM Level 3事件。因为它只执行jQuery 处理程序,你不会导致你需要的变化事件 触发更新文本框的value属性。
相反,您可以更新输入值并触发更改或输入事件:
input.val('x').trigger('input');
当在实时应用程序中的控制器内执行此操作(而不是在单元测试环境中)时,您需要突破$ digest周期,否则您将收到$apply already in progress
错误。
您可以使用setTimeout
:
$scope.trigger = function() {
setTimeout(function() {
$('input').val('x').trigger('input');
});
};
您还需要确保在AngularJS之前加载jQuery。如果不这样做,Angular将使用jqLite。 jqLite使用addEventHandler
来注册事件处理程序,并且以这种方式注册的处理程序不会被jQuery的trigger
函数触发。
您的代码演示已更新: http://plnkr.co/edit/u3ZWXWLvOjbKWlY8JEM5?p=preview
单元测试时:
it('should work', function() {
var element = $compile('<form name="form"><edit ng-model="name"></edit></form>')($scope);
$rootScope.$digest();
var scope = element.scope(),
form = scope.form,
input = element.find('input');
expect(form.$dirty).toBe(false);
input.val('x').trigger('input');
expect(form.$dirty).toBe(true);
});