як у angularjs як отримати доступ до елемента, який викликав подію?


93

Я використовую як 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.

Відповіді:


60
 updateTypeahead(this)

не передасть елемент DOM у функцію updateTypeahead(this). Тут thisбуде посилатися на сферу застосування. Якщо ви хочете отримати доступ до елемента DOM, використовуйте updateTypeahead($event). У функції зворотного дзвінка ви можете отримати елемент DOM за допомогою event.target.

Зверніть увагу: функція зміни ng не дозволяє передавати $ event як змінну.


65
ng-change не підтримує об'єкт події $ подія, переданий як параметр.
Марк Райкок

1
НГ-стиль не підтримує, як здається.
laggingreflex

4
Ухиляються теж. Не працює для ng-класу. $ подія не визначена! <li ng-repeat="item in items" role="menuitem" ng-class="{\'selected\' : isSelected($event, item)}">
Саад Бенбузід

4
Так добре, насправді не відповідає на питання, оскільки $ event не працює з ng-change: /
Адріан Томбу

1
мабуть, найбільш
завищена

74

Загальний кутовий спосіб отримати доступ до елемента, який викликав подію, - це написання директиви та прив’язання () до потрібної події:

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.

Деякі вбудовані директиви підтримують передачу $ події. Наприклад, ng- * клацання, ng-миша *. Зауважте, що ng-зміна не підтримує цю подію.

Хоча ви можете отримати елемент через об’єкт $ event:

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

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

це іде «глибоко проти кутового шляху» - Місько .


Хоча ваше рішення працює, воно не використовує формат DDO, що робить його дуже, дуже заплутаним, щоб з'ясувати, як додати / передати область прив'язки. Немає простого способу з вашого прикладу просто додати трохи цукру DDO для визначення масиву, і це здається так само глибоко "проти кутового шляху", як передача $ події від ng-клацання. Насправді в офіційній кутовій документації та прикладах коду я міг знайти жодного прикладу, який синтаксично схожий на ваш (тобто директива, що повертає лише анонімну функцію без жодного DDO).
tpartee

@tpartee, хороші моменти. Ще коли я писав цю відповідь, у кутових документах були приклади простих директив, які щойно повертали анонімну функцію (яка є функцією посилання). Я згоден, що DDO буде кращим в ці дні. Я оновив відповідь.
Марк Райчкок

Я думаю, що <button ng-click = "clickit ($ event.srcElement)"> було б краще
Carlos ABS

1
З плином часу я все більше переконуюсь у тому, що «кутовий шлях» надмірно
Jacob Stamm

7

Ви можете легко отримати подію цього першого події запису на елементі

ng-focus="myfunction(this)"

і у вашому js-файлі, як показано нижче

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

Я також ним користувався.


8
це повертає область дії, тому це не працюватиме належним чином.
vdclouis

1
Це взагалі не вирішує питання ОП. Звичайно, вона дозволяє одній функції знати, хто викликаний, але це не має жодного стосунку до виклику зміни ng, і немає зв'язку між ними. ОП потребує, щоб мати можливість посилатися на елемент, який викликав подію зміни ng в рамках виклику функції, який він робить.
tpartee

Це працює, додаючи атрибути (скажімо, id): alert (event.target.id).
Вейхуй Го

2

У контролері є рішення, що використовує елемент $, якщо ви не хочете створити іншу директиву для цієї проблеми:

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-зміною :

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

0

якщо ви хочете значення ng-моделі, якщо ви можете написати так у спрацьованій події: $ range.searchText


0

Я не впевнений, яку версію ви мали, але це питання задавали давно. Наразі за допомогою Angular 1.5 я можу використовувати ng-keypressподію та debounceфункцію від Lodash для імітації подібної поведінки на зразок ng-change, тому я можу захопити $ подія

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

$ range.edit = _.debounce (функція ($ подія) {console.log ("$ подія", $ подія)}, 800)


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.