使用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将使用jqLit​​e。 jqLit​​e使用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