使用 jQuery .trigger() 将 keydown 发送到 Angular 指令 [英] Sending keydown to Angular directive with jQuery .trigger()

查看:23
本文介绍了使用 jQuery .trigger() 将 keydown 发送到 Angular 指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个编辑指令来将 html 输入包装在一个漂亮的框架中.

I've created an edit directive to wrap an html input in a fancy frame.

现在我正在创建一个单元测试来检查一旦我输入了表单控制器的脏状态是否被设置.

Now I'm creating a unit test to check that once I type in the input the dirty state of the form controller is set.

我正在使用 jQuery.trigger() 来模拟这个,但我什么也没得到......

I'm using jQuery.trigger() to simulate this, but I get nothing...

var input = $('input');
var e = $.Event('keydown');
e.which = 'x'.charCodeAt(0);
e.keyCode = 'x'.charCodeAt(0);
input[0].focus();
input.trigger(e);

我有一个 plunker 这里

I have a plunker here

我做错了什么?

谢谢!

推荐答案

来自 回答类似问题:

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

The mistake you're making is what you're expecting the jQuery's trigger method to do. If you check out the code you'll see that what it is doing is actually executing the jQuery registered event handlers not the DOM Level 3 events. Because it's only executing jQuery handlers you wont be causing the change event which is what you need to be triggered to update the value property of the textbox.

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

Instead you can update the input's value and trigger the change or the input event:

input.val('x').trigger('input');

在实时应用程序中的控制器中执行此操作时(与单元测试环境相反),您需要打破 $digest 循环,否则您将获得 $apply 已经在进行中 错误.

When doing this inside a controller in a live application however (as opposed to in the unit test environment), you need to break out of the $digest cycle, or you will get the $apply already in progress error.

您可以通过例如使用 setTimeout 来做到这一点:

You can do this by for example using setTimeout:

$scope.trigger = function() {
  setTimeout(function() {
    $('input').val('x').trigger('input');
  });
};

您还需要确保在 AngularJS 之前加载 jQuery.如果不这样做,Angular 将使用 jqLit​​e.jqLit​​e 使用 addEventHandler 来注册事件处理程序,并且以这种方式注册的处理程序不会被 jQuery 的 trigger 函数触发.

You also need to make sure that you are loading jQuery before AngularJS. If you don't, Angular will use jqLite instead. jqLite uses addEventHandler to register event handlers, and handlers registered this way don't get triggered by jQuery's trigger function.

您的代码演示已更新: 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

这篇关于使用 jQuery .trigger() 将 keydown 发送到 Angular 指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆