【问题标题】:Sending keydown to Angular directive with jQuery .trigger()使用 jQuery .trigger() 将 keydown 发送到 Angular 指令
【发布时间】:2014-05-09 09:36:35
【问题描述】:

我创建了一个编辑指令来将 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

我做错了什么?

谢谢!

【问题讨论】:

    标签: jquery angularjs angularjs-directive


    【解决方案1】:

    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

    【讨论】:

    • 哎呀,我非常感谢您提出trigger('input') 部分。我尝试了keyup 之类的其他方法,但没有任何效果...非常感谢
    猜你喜欢
    • 1970-01-01
    • 2016-05-22
    • 2021-02-13
    • 1970-01-01
    • 2017-03-14
    • 1970-01-01
    • 2011-11-17
    • 2014-11-09
    • 2021-11-13
    相关资源
    最近更新 更多