【问题标题】:in angularjs how to access the element that triggered the event?在angularjs中如何访问触发事件的元素?
【发布时间】:2012-10-11 06:37:09
【问题描述】:

我在我的网络应用程序中同时使用 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 模块一起工作的最佳方法是什么。

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    获取触发事件的元素的一般 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>
    

    Plunker.

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

    一些内置指令支持传递 $event 对象。例如,ng-*click、ng-Mouse*。请注意,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,好点。回到我最初写这个答案的时候,角度文档确实有一些简单指令的例子,这些指令只返回了一个匿名函数(即链接函数)。我同意现在 DDO 会更好。我更新了答案。
    • 我认为
    • 随着时间的推移,我越来越相信“Angular 方式”架构过度且过于复杂
    【解决方案2】:
     updateTypeahead(this)
    

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

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

    【讨论】:

    • ng-change 不支持将事件对象 $event 作为参数传递。
    • ng-style 似乎也不支持。
    • 也被否决了。不适用于ng级。 $event 未定义! &lt;li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}"&gt;
    • 是的,没有真正回答这个问题,因为 $event 不适用于 ng-change :/
    • 可能是在 SO 上见过的评分最高的答案
    【解决方案3】:

    你可以像这样轻松获得第一个在元素上写事件

    ng-focus="myfunction(this)"
    

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

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

    我也用过。

    【讨论】:

    • 这会返回范围,所以这不会按预期工作。
    • 这根本不能解决 OP 的问题。当然,它让一个函数知道被调用者是谁,但这与 ng-change 调用无关,并且两者之间没有联系。 OP 需要的是能够在它所做的函数调用中引用触发 ng-change 事件的元素。
    • 这通过添加属性(比如,id)来工作:alert(event.target.id)。
    【解决方案4】:

    如果您不想为此问题创建另一个指令,则可以在控制器中使用 $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" />
    

    【讨论】:

      【解决方案5】:

      如果你想要 ng-model 值,如果你可以在触发事件中这样写: $scope.searchText

      【讨论】:

        【解决方案6】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2017-06-14
          • 1970-01-01
          • 2013-02-23
          • 1970-01-01
          • 1970-01-01
          • 2015-04-17
          • 1970-01-01
          • 2013-08-02
          • 1970-01-01
          相关资源
          最近更新 更多