Метод jQuery find() не работает в директиве AngularJS
У меня возникают проблемы с директивами angularjs, которые обнаруживают дочерние элементы DOM с введенным элементом angular.
Например, у меня есть такая директива:
myApp.directive('test', function () {
return {
restrict: "A",
link: function (scope, elm, attr) {
var look = elm.find('#findme');
elm.addClass("addedClass");
console.log(look);
}
};
});
и HTML, например:
<div ng-app="myApp">
<div test>TEST Div
<div id="findme"></div>
</div>
</div>
У меня есть доступ к элементу, который создается добавлением к нему класса.
Однако попытка доступа к дочернему элементу создает пустой массив в образе var.
Демо JSFiddle находится здесь.
Почему что-то настолько тривиальное не работает должным образом?
Ответы
Ответ 1
Из документов на angular.element
:
find()
- Ограничено поиском по имени тега
Итак, если вы не используете jQuery с Angular, но, опираясь на его реализацию jqlite, вы не можете сделать elm.find('#someid')
.
У вас есть доступ к реализациям children()
, contents()
и data()
, поэтому вы обычно можете найти способ обойти его.
Ответ 2
Вы можете легко решить это в 2 этапа:
1- Верните дочерний элемент с помощью querySelector следующим образом:
var target = element[0].querySelector('tbody tr:first-child td')
2- Преобразуйте его в объект angular.element
, выполнив следующие действия:
var targetElement = angular.element(target)
Затем вы получите доступ ко всем ожидаемым методам в переменной targetElement
.
Ответ 3
До дней jQuery вы будете использовать:
document.getElementById('findmebyid');
Если эта строка сохранит вам всю библиотеку jQuery, возможно, стоит использовать ее.
Для тех, кто обеспокоен производительностью:
Начинать селектор с идентификатором всегда лучше, поскольку он использует встроенную функцию document.getElementById.
// Fast:
$( "#container div.robotarm" );
// Super-fast:
$( "#container" ).find( "div.robotarm" );
http://learn.jquery.com/performance/optimize-selectors/
JSPerf
http://jsperf.com/jquery-selector-benchmark/32
Ответ 4
find()
- Ограничено поиском по имени тега
вы можете увидеть больше информации
https://docs.angularjs.org/api/ng/function/angular.element
Также вы можете получить доступ по имени или идентификатору или позвонить по следующему примеру:
angular.element(document.querySelector('#txtName')).attr('class', 'error');
Ответ 5
Я использовал
elm.children('.class-name-or-whatever')
чтобы получить дочерние элементы текущего элемента
Ответ 6
Если кто-то хочет захватить область действия элемента "контроллер как", то вот что:
<div id="firstctrl" ng-controller="firstCtrl as vm">
используйте следующее:
var vm = angular.element(document.querySelector('#firstctrl')).scope().vm;
Ответ 7
Вы можете сделать это следующим образом:
var myApp = angular.module('myApp', [])
.controller('Ctrl', ['$scope', function($scope) {
$scope.aaa = 3432
}])
.directive('test', function () {
return {
link: function (scope, elm, attr) {
var look = elm.children('#findme').addClass("addedclass");
console.log(look);
}
};
});
<div ng-app="myApp" ng-controller="Ctrl">
<div test>TEST Div
<div id="findme">{{aaa}}</div>
</div>
</div>
http://jsfiddle.net/FZGKA/133/