使用jQuery .trigger()将keydown发送到Angular指令

spa*_*gas 3 jquery angularjs angularjs-directive

我已经创建了一个编辑指令来将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);
Run Code Online (Sandbox Code Playgroud)

这里有一个傻瓜

我究竟做错了什么?

谢谢!

tas*_*ATT 5

从一个类似问题的答案:

你正在犯的错误就是你期望jQuery的触发器方法.如果查看代码,您将看到它正在执行的是实际执行jQuery注册事件处理程序而不是DOM Level 3事件.因为它只执行jQuery处理程序,所以您不会导致更改事件,这是您需要触发更新文本框的value属性的事件.

相反,您可以更新输入的值并触发更改或输入事件:

input.val('x').trigger('input');
Run Code Online (Sandbox Code Playgroud)

但是,当在实时应用程序中的控制器内执行此操作时(而不是在单元测试环境中),您需要打破$摘要周期,否则您将收到$apply already in progress错误.

您可以通过以下方式执行此操作setTimeout:

$scope.trigger = function() {
  setTimeout(function() {
    $('input').val('x').trigger('input');
  });
};
Run Code Online (Sandbox Code Playgroud)

您还需要确保在AngularJS之前加载jQuery.如果不这样做,Angular将使用jqLit​​e.jqLit​​e用于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);
});
Run Code Online (Sandbox Code Playgroud)

单元测试演示: http ://plnkr.co/edit/Emc3dIlDaxXyE9U6dEG6?p = preview