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.