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

时间:2014-05-09 09:36:36

标签: 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);

我有一个羽毛here

我做错了什么?

谢谢!

1 个答案:

答案 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将使用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);
});

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