Угловой JS доступ к элементам DOM внутри шаблона директивы
Есть ли способ "angular" выбрать элементы DOM внутри шаблона директивы? Например, скажем, у вас есть эта директива:
app.directive("myDirective", function() {
return {
template: '<div><ul><li ng-repeat="item in items"></ul></div>',
link: function(scope, element, attrs) {
var list = element.find("ul");
}
}
});
Я использовал селектор стиля jQuery, чтобы получить элемент DOM <ul>
, выделенный в моем шаблоне. Есть ли лучший способ сделать это?
Ответы
Ответ 1
Вы можете написать для этого директиву, которая просто присваивает элемент (jqLite) области видимости с именем, заданным атрибутом.
Вот директива:
app.directive("ngScopeElement", function () {
var directiveDefinitionObject = {
restrict: "A",
compile: function compile(tElement, tAttrs, transclude) {
return {
pre: function preLink(scope, iElement, iAttrs, controller) {
scope[iAttrs.ngScopeElement] = iElement;
}
};
}
};
return directiveDefinitionObject;
});
Использование:
app.directive("myDirective", function() {
return {
template: '<div><ul ng-scope-element="list"><li ng-repeat="item in items"></ul></div>',
link: function(scope, element, attrs) {
scope.list[0] // scope.list is the jqlite element,
// scope.list[0] is the native dom element
}
}
});
Некоторые замечания:
- Благодаря компиляции и порядку ссылок для вложенных директив вы можете получить доступ только к
scope.list
из myDirective
postLink-Function, которые вы очень вероятно, используя в любом случае
-
ngScopeElement
использует функцию preLink, так что директивы, вложенные в элемент, имеющий ng-scope-element
, уже могут получить доступ к scope.list
- не уверен, как это ведет себя с точки зрения производительности
Ответ 2
Я не думаю, что для выбора элемента существует более "angular способ". См., Например, то, как они достигают этой цели в последнем примере этой старой страницы документации:
{
template: '<div>' +
'<div class="title">{{title}}</div>' +
'<div class="body" ng-transclude></div>' +
'</div>',
link: function(scope, element, attrs) {
// Title element
var title = angular.element(element.children()[0]),
// ...
}
}
Ответ 3
Этот ответ приходит немного позже, но я просто нуждался.
Наблюдение за комментариями, написанными @ganaraj в вопросе, Один случай использования, в котором я нуждался, - передать имя класса через атрибут директивы, который будет добавлен в тег ng-repeat li в шаблоне.
Например, используйте следующую директиву:
<my-directive class2add="special-class" />
И получите следующий html:
<div>
<ul>
<li class="special-class">Item 1</li>
<li class="special-class">Item 2</li>
</ul>
</div>
Решение найдено здесь, применяемое с templateUrl, будет:
app.directive("myDirective", function() {
return {
template: function(element, attrs){
return '<div><ul><li ng-repeat="item in items" class="'+attrs.class2add+'"></ul></div>';
},
link: function(scope, element, attrs) {
var list = element.find("ul");
}
}
});
Просто попробовал это с помощью AngularJS 1.4.9.
Надеюсь, что это поможет.