AngularJS - найти элемент с атрибутом
Я новичок в AngularJS. Я узнал, что могу найти элементы в DOM, используя следующие запросы:
var e = angular.element(document.querySelector('#id'));
var e = angular.element(elem.querySelector('.classname'));
Это полезно для поиска элементов по идентификатору или имени класса CSS. Однако мне нужно найти элемент, используя другой подход. У меня есть элемент, который выглядит следующим образом:
<div my-directive class='myContainer'>...</div>
Я не могу запросить "myContainer" из-за того, насколько он повторно используется. По этой причине я хотел бы найти любой элемент с атрибутом 'my-directive'. Как выполнить поиск в DOM и найти любой элемент, который использует "my-directive"?
Ответы
Ответ 1
Вместо запроса DOM для элементов (который не очень похож на angular см. "Мышление в AngularJS" , если у меня есть фон jQuery?), вы должны выполните свою DOM-манипуляцию в своей директиве. Элемент доступен вам в вашей функции ссылок.
Итак, в вашем myDirective
return {
link: function (scope, element, attr) {
element.html('Hello world');
}
}
Если вы должны выполнить запрос за пределами директивы, тогда было бы возможно использовать querySelectorAll в современных браузерах
angular.element(document.querySelectorAll("[my-directive]"));
однако вам нужно будет использовать jquery для поддержки IE8 и назад
angular.element($("[my-directive]"));
или напишите свой собственный метод, как показано здесь Получить элементы по атрибуту, когда querySelectorAll недоступен без использования библиотек?
Ответ 2
Ваш прецедент не ясен. Однако, если вы уверены, что вам нужно, чтобы это было основано на DOM, а не на данных модели, то это способ для одной директивы иметь ссылку на все элементы с другой директивой, указанной на них.
Способ состоит в том, что дочерняя директива может require
родительскую директиву. Директива parent может выставить метод, который позволяет прямой директиве регистрировать свой элемент с родительской директивой. Благодаря этому родительская директива может получить доступ к дочернему элементу (элементам). Поэтому, если у вас есть шаблон, например:
<div parent-directive>
<div child-directive></div>
<div child-directive></div>
</div>
Тогда директивы могут быть закодированы следующим образом:
app.directive('parentDirective', function($window) {
return {
controller: function($scope) {
var registeredElements = [];
this.registerElement = function(childElement) {
registeredElements.push(childElement);
}
}
};
});
app.directive('childDirective', function() {
return {
require: '^parentDirective',
template: '<span>Child directive</span>',
link: function link(scope, iElement, iAttrs, parentController) {
parentController.registerElement(iElement);
}
};
});
Это можно увидеть в действии http://plnkr.co/edit/7zUgNp2MV3wMyAUYxlkz?p=preview
Ответ 3
Вы не указали, где вы ищете элемент. Если это входит в сферу действия контроллера, возможно, несмотря на хор, который вы услышите об этом, не являясь "Angular Way". Хор хорош, но иногда, в реальном мире, это неизбежно. (Если вы не согласны, свяжитесь с нами - у меня есть вызов для вас.)
Если вы передадите $element
в контроллер, как и вы, $scope
, вы можете использовать его функцию find()
. Обратите внимание, что в jQueryLite, включенном в Angular, find()
будет определять метки только по имени, а не по атрибуту. Однако, если вы включите полномасштабный jQuery в свой проект, можно использовать все функции find()
, включая поиск по атрибуту.
Итак, для этого HTML:
<div ng-controller='MyCtrl'>
<div>
<div name='foo' class='myElementClass'>this one</div>
</div>
</div>
Этот код AngularJS должен работать:
angular.module('MyClient').controller('MyCtrl', [
'$scope',
'$element',
'$log',
function ($scope, $element, $log) {
// Find the element by its class attribute, within your controller scope
var myElements = $element.find('.myElementClass');
// myElements is now an array of jQuery DOM elements
if (myElements.length == 0) {
// Not found. Are you sure you've included the full jQuery?
} else {
// There should only be one, and it will be element 0
$log.debug(myElements[0].name); // "foo"
}
}
]);