Когда отдать предпочтение нг-если против нг-шоу / нг-скрыть?

460

Я понимаю, что ng-show и ng-hide влияют на набор классов для элемента и что ng-if управляет тем, отображается ли элемент как часть DOM.

Есть ли рекомендации по выбору ng-if над ng-show/ng-hide или наоборот?

Теги:
angularjs-directive

8 ответов

645
Лучший ответ

Зависит от вашего варианта использования, но суммирует разницу:

  • ng-if удалит элементы из DOM. Это означает, что все ваши обработчики или что-либо еще, прикрепленное к этим элементам, будут потеряны. Например, если вы привязали обработчик клика к одному из дочерних элементов, когда ng-if оценивается как false, этот элемент будет удален из DOM, и обработчик вашего клика больше не будет работать, даже после того, как ng-if позже оценит значение true и отображает элемент. Вам нужно будет снова привязать обработчик.
  • ng-show/ng-hide не удаляет элементы из DOM. Он использует стили CSS, чтобы скрыть/показать элементы (обратите внимание: вам может потребоваться добавить свои собственные классы). Таким образом, ваши обработчики, которые были привязаны к детям, не будут потеряны.
  • ng-if создает дочернюю область, а ng-show/ng-hide не

Элементы, не входящие в DOM, имеют меньшее влияние на производительность, и ваше веб-приложение может показаться более быстрым при использовании ng-if по сравнению с ng-show/ng-hide. По моему опыту, разница незначительна. Анимация возможна при использовании ng-show/ng-hide и ng-if, с примерами для обеих в документации Angular.

В конечном счете, на вопрос, который вам нужно ответить, можно ли удалить элемент из DOM или нет?

  • 18
    Вы можете использовать CSS3 анимацию с помощью ng-if . Проверьте параграф Анимации и пример в документах . Также с помощью ng-hide/ng-show селекторы css, такие как :first-child или :nth-child , не будут работать должным образом, так как скрытые элементы также будут учитываться.
  • 3
    Сервис анимации в angular.dart является относительно новым. На момент написания этого он был недоступен.
Показать ещё 14 комментариев
116

Смотрите здесь для CodePen, который демонстрирует разницу в том, как работает ng-if/ng-show, DOM-wise.

@markovuksanovic ответил на вопрос хорошо. Но я пришел к этому с другой точки зрения: я всегда использовал ng-if и вытаскивал эти элементы из DOM, если:

  • вам почему-то нужны привязки данных и $watch -es на ваших элементах, чтобы оставаться активными, пока они невидимы. Формы могут быть хорошим примером для этого, если вы хотите иметь возможность проверить достоверность на входах, которые в настоящее время не видны, чтобы определить, действительна ли вся форма.
  • Вы используете некоторую действительно сложную логику состояния с обработчиками условных событий, как упоминалось выше. Тем не менее, если вы обнаружите, что вручную привязываете и отключаете обработчики, чтобы потерять важное состояние при использовании ng-if, спросите себя, будет ли это состояние лучше представлено в модели данных, а обработчики будут применяться условно по директивам всякий раз элемент визуализируется. Другими словами, наличие/отсутствие обработчиков является формой данных состояния. Получите эти данные из DOM и в модель. Наличие/отсутствие обработчиков должно определяться данными и, следовательно, легко воссоздаваться.

Angular написано очень хорошо. Это быстро, учитывая, что он делает. Но то, что он делает, - это целая куча магии, которая делает тяжелые вещи (например, привязку к двум каналам) выглядят тривиально легко. Учет всех этих вещей влечет за собой некоторые издержки производительности. Вы можете быть шокированы, чтобы понять, сколько сотен или тысяч раз функция сеттера оценивается во время цикла $digest на куске DOM, на который никто даже не смотрит. И тогда вы понимаете, что у вас есть десятки или сотни невидимых элементов, которые делают одно и то же...

Настольные компьютеры действительно могут быть достаточно мощными, чтобы справляться с большинством проблем с производительностью JS. Но если вы разрабатываете для мобильных устройств, используя ng - если всякий раз, когда человеческое поведение должно быть без проблем. Скорость JS по-прежнему имеет значение для мобильных процессоров. Использование ng-if - очень простой способ получить потенциально значимую оптимизацию по очень низкой цене.

  • 5
    Очень хорошее дополнение к ответу выше. Дано с хорошим контекстом, который также помогает в принятии решений. Благодарю.
  • 1
    ng-show может быть полезно, когда у вас есть, скажем, вкладки, каждая из которых содержит много контента, который занимает время для визуализации. После первого рендеринга перемещение между вкладками будет мгновенным, тогда как ng-if потребует повторного рендеринга, привязывания событий и т. Д. Как вы можете сказать, недостатком является создание часов, выполняющихся в фоновом режиме. Angular отчаянно нуждается в ng-ifshowwatch
48

Из моего опыта:

1) Если ваша страница имеет переключатель, который использует ng-if/ng-show, чтобы показать/скрыть что-то, ng-if вызывает больше задержки браузера (медленнее). Например: если у вас есть кнопка, используемая для переключения между двумя представлениями, ng-show кажется более быстрым.

2) ng-if будет создавать/уничтожать область действия, когда она оценивает значение true/false. Если у вас есть контроллер, подключенный к ng-if, этот код контроллера будет выполняться каждый раз, когда ng-if будет иметь значение true. Если вы используете ng-show, код контроллера запускается только один раз. Поэтому, если у вас есть кнопка, которая переключается между несколькими видами, использование ng-if и ng-show будет иметь огромное значение в том, как вы пишете свой код контроллера.

  • 4
    Это огромная правда! нг-если не обязательно сделать ваш интерфейс быстрее. Это зависит от ваших потребностей. На самом деле это может быть наоборот, если вы используете в неправильной ситуации.
  • 1
    Но, по моему мнению, ng-if не рендерится на DOM, поэтому он быстрый по сравнению с ng-show / hide. я не прав, пожалуйста, дайте мне исправить в этой точке.
Показать ещё 3 комментария
26

Ответ прост:

Это зависит от целевых компьютеров (мобильных и настольных), это зависит от характера ваших данных, браузера, ОС, аппаратного обеспечения, на котором оно работает... вам нужно будет проверить, действительно ли вы хотите знать.

В основном проблема памяти и вычислений... как и при большинстве проблем с производительностью, разница может стать значимой с повторяющимися элементами (n), такими как списки, особенно когда вложенные (nxn или, что еще хуже), а также какие вычисления вы выполняете внутри этих элементов:

  • ng-show: если эти необязательные элементы часто присутствуют (плотные), например, 90% времени, возможно, быстрее их подготовить и показать или скрыть, особенно если их содержимое дешево (просто текст, ничего не вычислять или загружать). Это потребляет память, поскольку она заполняет DOM скрытыми элементами, но просто показать/скрыть что-то, что уже существует, вероятно, будет дешевой операцией для браузера.

  • ng-if: если, напротив, элементы не будут отображаться (разрежены), просто создавайте их и уничтожайте их в режиме реального времени, особенно если их содержимое дорого получается ( вычисления/сортировка/фильтрация, изображения, сгенерированные изображения). Это идеально подходит для редких или "по требованию" элементов, оно экономит память с точки зрения не заполнения DOM, но может стоить много вычислений (создания/уничтожения элементов) и полосы пропускания (получения удаленного контента). Это также зависит от того, сколько вы вычислите в представлении (фильтрация/сортировка) по сравнению с тем, что у вас уже есть в модели (предварительно отсортированные/предварительно отфильтрованные данные).

  • 2
    Другие ответы на технические факты. Это для мудрости. Вы четко создали нетривиальные приложения Angular, сэр! +1
  • 0
    Эта проблема выходит за рамки угловой, это фундаментальная проблема в информатике, есть точка, с которой один метод более эффективен, чем другой. Обычно это можно найти с помощью некоторого сравнительного анализа. Таким образом, вы можете даже переключаться между одним методом и другим в зависимости от количества элементов ... Подобная тема: math.stackexchange.com/questions/1632739/…
11

Одно важное замечание:

ngIf (в отличие от ngShow) обычно создает дочерние области, которые могут создавать неожиданные результаты.

У меня была проблема, связанная с этим, и я потратил много времени, чтобы выяснить, что происходит.

(Моя директива записывала свои значения модели в неправильную область.)

Итак, чтобы сохранить ваши волосы, просто используйте ngShow, если вы не запустите слишком медленно.

В любом случае разница в производительности практически не известна, и я пока не уверен, кто пользуется этим без теста...

  • 8
    Использование $parent.scopevar в привязках данных в ngIf исправит проблемы, связанные с дочерними областями, при использовании ngIf
  • 2
    Это не совсем верно (то есть оригинальный комментарий @ user2173353). Если вы будете придерживаться хорошей практики, у вас не будет проблем. Это довольно простое правило: «если нет точки, значит, вы делаете это неправильно». Смотрите здесь для демонстрации того, как это работает: bit.ly/1SPv4wL . Еще одна замечательная ссылка (см. Ошибку № 2): bit.ly/1QfFeWd > (Моя директива записывала значения своей модели в неправильную область.) Это результат того, что мы не придерживались вышеуказанной практики.
Показать ещё 2 комментария
3

Если вы используете ng-show or ng-hide, содержимое (например, миниатюры с сервера) будет загружено независимо от значения выражения, но будет отображаться на основе значения выражения.

Если вы используете ng-if, контент будет загружен только в том случае, если выражение ng-if оценивается как правдивое.

Использование ng-if - хорошая идея в ситуации, когда вы собираетесь загружать данные или изображения с сервера и показывать их только в зависимости от взаимодействия пользователей. Таким образом, загрузка вашей страницы не будет блокироваться ненужными интенсивными задачами nw.

  • 0
    Это особенно полезно, так как большинство браузеров будут загружать изображения, даже если CSS скрывает свои DOM-контейнеры. Обычно они просто ищут атрибут src тега img , когда он присутствует, он загружается!
2

ng-if на ng-include и на ng-контроллере будет иметь большое влияние на ng-include он не будет загружать требуемые частичные и не обрабатывается, если флаг не является истинным на ng-контроллере он не будет загружать контроллер, если флаг не верен но проблема в том, что флаг становится ложным в ng - если он удалит из DOM, когда флаг вернется обратно, он перезагрузит DOM, в этом случае ng-show лучше, за один раз покажите ng-if лучше

0

нг-, если

более эффективен, поскольку он решает, нужно ли отображать элемент html или нет. Кроме того, в то же время он решает, создавать ли область и связывать элемент html или нет. Это помогает в производительности.

  • ng-hide аналогична функции jquery hide() и show(), где элемент не отображается пользователю, но существует в DOM.

нг-шоу

будет отображать ваш html-элемент и связывать область также, но просто скрыть и показать html-элемент на экране. Зарегистрированные наблюдатели примут участие в дайджест-кайле, независимо от того, скрыт ли элемент или нет. Следовательно, это повлияет на производительность.

  • ng-if похоже на jquery remove() funtion, он не только скрывает элемент, но и также удалите из DOM.

Пример

ng-show=true/ng-hide=false//show the element
ng-show=false/ng-hide=true//hide the element
ng-if =true//show the element from the DOM 
ng-if= false//removes the element from the DOM 

Всегда, используйте ng-if вместо ng-show/ng-hide

Ещё вопросы

Сообщество Overcoder
Наверх
Меню