Angular.element vs document.getElementById или селектор jQuery со спин (занятым) управлением
Я использую "Угловую" версию управления Spin, как описано здесь: http://blog.xvitcoder.com/adding-a-weel-progress-indicator-to-your-angularjs-application/
Одна из вещей, которые мне не нравятся в показанном решении, - это использование jQuery в службе, которая эффективно прикрепляет элемент управления спином к элементу DOM. Я бы предпочел использовать конструкторы angular для доступа к элементу. Я также хотел бы избежать "жесткого кодирования" идентификатора элемента, который должен быть подключен прядильщиком внутри службы, и вместо этого использовать директиву, которая устанавливает идентификатор в службе (singleton), чтобы другие пользователи службы или сама услуга не нуждается в этом.
Я борюсь с тем, что angular.element дает нам что-то, что document.getElementById на том же идентификаторе элемента дает нам.
например. Это работает:
var target = document.getElementById('appBusyIndicator');
Ничего из этого не делают:
var target = angular.element('#appBusyIndicator');
var target = angular.element('appBusyIndicator');
Я явно делаю то, что должно быть довольно очевидно неправильно! Может ли кто-нибудь помочь?
Предполагая, что я могу получить вышеописанную работу, у меня есть аналогичная проблема с попыткой заменить доступ к элементу jQuery:
например, $(target).fadeIn('fast');
работает angular.element('#appBusyIndicator').fadeIn('fast')
или angular.element('appBusyIndicator').fadeIn('fast')
не
Может ли кто-нибудь указать мне хороший пример документации, в которой разъясняется использование элемента angular "и элемента DOM? angular явно" обертывает "элемент своими собственными свойствами, методами и т.д., но часто бывает трудно получить исходное значение. Например, если у меня есть поле <input type='number'>
, и я хочу получить доступ к исходному содержимому, которое отображается в ui, когда пользователь набирает" - "(без кавычек), я ничего не получаю, по-видимому, потому что" type = number" означает angular отклоняет ввод, даже если он отображается в пользовательском интерфейсе, и я хочу его увидеть, поэтому я могу проверить его и очистить.
Любые указатели/ответы оценены.
Спасибо.
Ответы
Ответ 1
Он может работать следующим образом:
var myElement = angular.element( document.querySelector( '#some-id' ) );
Вы завершаете вызов Document.querySelector()
собственный Javascript в вызов angular.element()
. Таким образом, вы всегда получаете элемент в объекте jqLite или jQuery, в зависимости от того, доступен или нет jQuery
.
Официальная документация для angular.element
:
Если доступно jQuery, angular.element
является псевдонимом для функции jQuery
. Если jQuery недоступен, angular.element
делегирует встроенное подмножество Angulars в jQuery
, которое называется "jQuery lite" или jqLite.
Все ссылки на элементы в Angular
всегда завернуты в jQuery или jqLite
(например, аргумент element в функции компиляции директив или ссылки). Они никогда не являются исходными ссылками DOM
.
Если вы задаетесь вопросом, зачем использовать Document.querySelector()
, прочитайте этот ответ.
Ответ 2
Вы должны прочитать документы angular element, если вы еще этого не сделали, поэтому вы можете понять, что поддерживается jqLite, а что нет - jqlite подмножество jquery, встроенное в angular.
Эти селекторы не будут работать только с jqLite, так как селектора по id не поддерживаются.
var target = angular.element('#appBusyIndicator');
var target = angular.element('appBusyIndicator');
Итак, либо:
- вы используете только jqLite, более ограниченный jQuery, но достаточно в большинстве ситуаций.
- или вы включаете полную библиотеку jQuery в свое приложение и используете ее как обычный jquery в тех местах, где вам действительно нужен jquery.
Изменить: обратите внимание, что jQuery должен быть загружен до angularJS, чтобы иметь преимущество над jqLite:
Реальный jQuery всегда имеет приоритет над jqLite, если он загружен до запуска события DOMContentLoaded.
Edit2: Я пропустил вторую часть вопроса раньше:
Проблема с <input type="number">
, я думаю, что это не проблема angular, это предполагаемое поведение элемента native html5.
Он не вернет нечисловое значение, даже если вы попытаетесь получить его с помощью jquery .val()
или с помощью атрибута raw .value
.
Ответ 3
var target = document.getElementById('appBusyIndicator');
равно
var target = $document[0].getElementById('appBusyIndicator');
Ответ 4
Я не думаю, что это правильный способ использовать angular. Если метод framework не существует, не создавайте его! Это означает, что структура (здесь angular) не работает таким образом.
С angular вам не следует манипулировать DOM, как это (путь jquery), но используйте вспомогательный angular, например
<div ng-show="isLoading" class="loader"></div>
Или создайте свою собственную директиву (свой собственный компонент DOM), чтобы иметь полный контроль над ней.
Кстати, вы можете увидеть здесь http://caniuse.com/#search=queryselector querySelector хорошо поддерживается и поэтому можно безопасно использовать.
Ответ 5
Вы можете получить доступ к элементам с помощью $document (требуется ввести документ $)
var target = $document('#appBusyIndicator');
var target = $document('appBusyIndicator');
или с элементом angular, к указанным элементам можно обращаться как:
var targets = angular.element(document).find('div'); //array of all div
var targets = angular.element(document).find('p');
var target = angular.element(document).find('#appBusyIndicator');
Ответ 6
Вы должны ввести $document в свой контроллер и использовать его вместо исходного объекта документа.
var myElement = angular.element($document[0].querySelector('#MyID'))
Если вам не нужен перенос элемента стиля jQuery, $document [0].querySelector('# MyID') предоставит вам объект DOM.
Ответ 7
Если кто-то использует gulp, он показывает ошибку, если мы используем document.getElementById()
, и предлагаем использовать $document.getElementById()
, но он не работает.
Использование -
$document[0].getElementById('id')
Ответ 8
Это сработало для меня хорошо.
angular.forEach(element.find('div'), function(node)
{
if(node.id == 'someid'){
//do something
}
if(node.className == 'someclass'){
//do something
}
});
Ответ 9
Улучшение ответа кайзера:
var myEl = $document.find('#some-id');
Не забудьте ввести $document
в свою директиву
Ответ 10
Может быть, я слишком поздно здесь, но это сработает:
var target = angular.element(appBusyIndicator);
Обратите внимание, что нет appBusyIndicator
, это простое значение идентификатора.
Что происходит за кулисами: (при условии, что оно применяется к div)
(взято из angular.js строка №: 2769 и далее...)
/////////////////////////////////////////////
function JQLite(element) { //element = div#appBusyIndicator
if (element instanceof JQLite) {
return element;
}
var argIsString;
if (isString(element)) {
element = trim(element);
argIsString = true;
}
if (!(this instanceof JQLite)) {
if (argIsString && element.charAt(0) != '<') {
throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
}
return new JQLite(element);
}
По умолчанию, если на странице нет jQuery, будет использоваться jqLite. Аргумент внутренне понимается как id и возвращается соответствующий объект jQuery.