使用jQuery .trigger()将keydown发送到Angular指令
我已经创建了一个编辑指令来将html输入包装在一个奇特的框架中。
现在我正在创建一个unit testing来检查一旦输入输入,就会设置表单控制器的脏状态。
我正在使用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);
我这里有一个傻瓜
我究竟做错了什么?
谢谢!
从一个类似问题的答案 :
你正在犯的错误是你期望jQuery的触发器方法。 如果您查看代码,您将看到它正在执行的是实际执行jQuery注册事件处理程序而不是DOM Level 3事件。 因为它只执行jQuery处理程序,所以您不会导致更改事件,这是您需要触发更新文本框的value属性的事件。
相反,您可以更新输入的值并触发更改或输入事件:
input.val('x').trigger('input');
但是,当在实时应用程序中的控制器内执行此操作时(而不是在unit testing环境中),您需要突破$ digest循环,否则您将获得$apply already in progress
错误。
您可以通过使用setTimeout
执行此操作:
$scope.trigger = function() { setTimeout(function() { $('input').val('x').trigger('input'); }); };
您还需要确保在AngularJS之前加载jQuery。 如果不这样做,Angular将使用jqLite。 jqLite使用addEventHandler
来注册事件处理程序,并且以这种方式注册的处理程序不会被jQuery的trigger
函数trigger
。
您的代码演示已更新: http : //plnkr.co/edit/u3ZWXWLvOjbKWlY8JEM5?p = preview
unit testing时:
it('should work', function() { var element = $compile('')($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); });
unit testing演示: http : //plnkr.co/edit/Emc3dIlDaxXyE9U6dEG6?p = preview