在angularjs中如何访问触发事件的元素?


93

我在我的Web应用程序中同时使用了Bootstrap和AngularJS。我很难让两个人一起工作。

我有一个元素,它具有属性 data-provide="typeahead"

<input id="searchText" ng-model="searchText" type="text"
       class="input-medium search-query" placeholder="title"
       data-provide="typeahead" ng-change="updateTypeahead()" />

我想data-source在用户在字段中输入时更新属性。该函数updateTypeahead已正确触发,但是除非我使用$('#searchText'),这是jQuery方式,而不是AngularJS方式,否则我无法访问触发事件的元素。

使AngularJS与旧式JS模块一起工作的最佳方法是什么。

Answers:


60
 updateTypeahead(this)

不会将DOM元素传递给函数updateTypeahead(this)。这里this将参考范围。如果要访问DOM元素,请使用updateTypeahead($event)。在回调函数中,您可以通过获取DOM元素event.target

请注意:ng-change函数不允许将$ event作为变量传递。


65
ng-change不支持将事件对象$ event作为参数传递。
Mark Rajcok

1
ng-style似乎不支持。
laggingreflex 2014年

4
也被否决了。不适用于ng级。$ event未定义!<li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}">
萨德·本布兹

4
是的,没有真正回答问题,因为$ event不能与ng-change配合使用:/
Adrian Tombu

1
可能是SO上
收视率

74

访问触发事件的元素的一般Angular方法是编写指令并将bind()绑定到所需的事件:

app.directive('myChange', function() {
  return function(scope, element) {
    element.bind('change', function() {
      alert('change on ' + element);
    });
  };
});

或使用DDO(根据下面的@tpartee的评论):

app.directive('myChange', function() {
  return { 
    link:  function link(scope, element) {
      element.bind('change', function() {
        alert('change on ' + element);
      });
    }
  }
});

上面的指令可以如下使用:

<input id="searchText" ng-model="searchText" type="text" my-change>

柱塞

在文本字段中键入,然后离开/模糊。更改回调函数将触发。在该回调函数中,您可以访问element

一些内置指令支持传递$ event对象。例如,ng- *单击,ng-鼠标*。请注意,ng-change不支持此事件。

虽然可以通过$ event对象获取元素:

<button ng-click="clickit($event)">Hello</button>

$scope.clickit = function(e) {
    var elem = angular.element(e.srcElement);
    ...

这就是“深深地反对Angular方式” -Misko


虽然您的解决方案可以正常工作,但它不使用DDO格式,这使弄清楚如何向绑定中添加/传递范围变得非常混乱。在您的示例中,没有简单的方法来简单地添加一些DDO糖进行作用域,这似乎与从ng-click传递$ event一样深深地“反对Angular方式”。实际上,在Angular官方文档和代码示例中,我找不到一个与您的语法在语法上相似的示例(即,一个仅返回匿名函数而没有任何DDO的指令)。
tpartee

@tpartee,要点。回到我最初编写此答案时,Angular文档确实有一些简单指令的示例,这些指令仅返回了一个匿名函数(即链接函数)。我同意DDO最近会更好。我更新了答案。
Mark Rajcok '16

我认为<button ng-click =“ clickit($ event.srcElement)”>会更好
Carlos ABS

1
随着时间的流逝,我越来越相信“角度方式”的架构和复杂性过高
Jacob Stamm,

7

您可以像在元素上的第一个write事件一样轻松获得

ng-focus="myfunction(this)"

在您的js文件中,如下所示

$scope.myfunction= function (msg, $event) {
    var el = event.target
    console.log(el);
}

我也用过它。


8
这将返回范围,因此将无法按预期工作。
vdclouis

1
这根本无法解决OP的问题。当然,它可以使一个函数知道被调用的对象是谁,但是这与ng-change调用无关,并且两者之间没有任何联系。OP需要的是能够引用在其进行的函数调用中触发ng-change事件的元素。
tpartee

通过添加以下属性(例如ID)来工作:alert(event.target.id)。
郭卫辉

2

如果您不想为此问题创建另一个指令,则可以在控制器中使用$ element解决方案:

appControllers.controller('YourCtrl', ['$scope', '$timeout', '$element',
        function($scope, $timeout, $element) {

    $scope.updateTypeahead = function() {
       // ... some logic here
       $timeout(function() {
           $element[0].getElementsByClassName('search-query')[0].focus();
           // if you have unique id you can use $window instead of $element:
           // $window.document.getElementById('searchText').focus();
       });
    }
}]);

这将与ng-change一起工作:

<input id="searchText" type="text" class="search-query" ng-change="updateTypeahead()" ng-model="searchText" />

0

如果您想使用ng-model值,则可以在触发的事件中这样写:$ scope.searchText


0

我不确定您使用的是哪个版本,但是很久以前就问过这个问题。目前在Angular 1.5中,我可以使用ng-keypress Lodash中事件和debounce函数来模拟类似的行为,因此我可以捕获$ eventng-change

<input type="text" ng-keypress="edit($event)" ng-model="myModel">

$ scope.edit = _.debounce(function($ event){console.log(“ $ event”,$ event)},800)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.