Когда отдать предпочтение нг-если против нг-шоу / нг-скрыть?
Я это понимаю ng-show
а также ng-hide
влияет на класс, установленный на элементе и ng-if
контролирует, отображается ли элемент как часть DOM.
Есть ли рекомендации по выбору ng-if
над ng-show
/ ng-hide
или наоборот?
7 ответов
Зависит от вашего варианта использования, но суммируя разницу:
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 или нет?
Смотрите здесь для CodePen, который демонстрирует разницу в том, как работает ng-if / ng-show, с точки зрения DOM.
@markovuksanovic хорошо ответил на вопрос. Но я бы пришел к этому с другой точки зрения: я всегда использовал ng-if
и получить эти элементы из DOM, если:
- вам почему-то нужны привязки данных и
$watch
- ваши элементы остаются активными, пока они невидимы. Формы могут быть хорошим примером для этого, если вы хотите иметь возможность проверять достоверность входных данных, которые в данный момент не видны, чтобы определить, является ли вся форма действительной. - Вы используете действительно сложную логику состояния с обработчиками условных событий, как упомянуто выше. Тем не менее, если вы обнаружите, что вручную подключаете и отключаете обработчики, так что вы теряете важное состояние при использовании ng-if, спросите себя, будет ли это состояние лучше представлено в модели данных, а обработчики применяются условно с помощью директив всякий раз, когда элемент отображается Другими словами, наличие / отсутствие обработчиков является формой данных о состоянии. Получите эти данные из DOM и в модель. Наличие / отсутствие обработчиков должно определяться данными, и, следовательно, их легко воссоздать.
Angular написан очень хорошо. Это быстро, учитывая, что он делает. Но то, что он делает, - это целая куча магии, которая делает сложные вещи (например, двухстороннее связывание данных) тривиально простыми. Чтобы все это выглядело легко, нужно немного снизить производительность. Вы можете быть потрясены, когда поймете, сколько сотен или тысяч раз оценивается функция сеттера во время $digest
Цикл на кусок DOM, на который никто даже не смотрит. И тогда вы понимаете, что у вас есть десятки или сотни невидимых элементов, которые делают одно и то же...
Рабочие столы действительно могут быть достаточно мощными, чтобы сделать большинство проблем со скоростью выполнения JS спорными. Но если вы разрабатываете для мобильных устройств, использование ng-if, когда это возможно, должно быть легким делом. Скорость JS по-прежнему важна для мобильных процессоров. Использование ng-if - это очень простой способ получить потенциально значимую оптимизацию при очень и очень низких затратах.
Из моего опыта:
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 очень сильно изменит способ написания кода контроллера.
Ответ не прост:
Это зависит от целевых машин (мобильный или настольный компьютер), от природы ваших данных, браузера, операционной системы, аппаратного обеспечения, на котором он работает... вам нужно будет тестировать, если вы действительно хотите знать.
В основном это проблема памяти против вычислений... так как с большинством проблем производительности разница может стать значительной с повторяющимися элементами (n), такими как списки, особенно когда они вложенные (n x n или хуже), а также какие вычисления вы выполняете внутри этих элементов:
ng-show: если эти необязательные элементы часто присутствуют (плотно), как, например, в 90% случаев, может быть быстрее подготовить их и только показать / скрыть их, особенно если их содержимое дешевое (просто текст, ничего вычислить или загрузить). Это потребляет память, так как заполняет DOM скрытыми элементами, но просто показать / скрыть то, что уже существует, вероятно, будет дешевой операцией для браузера.
ng-if: если элементы, скорее всего, не будут отображаться (разреженно), просто создайте их и уничтожьте их в реальном времени, особенно если их содержимое требует больших затрат (вычисления / сортировка / фильтрация, изображения, сгенерированные изображения). Это идеально для редких элементов или элементов "по требованию", оно экономит память с точки зрения незаполнения DOM, но может стоить больших вычислений (создание / уничтожение элементов) и пропускной способности (получение удаленного контента). Это также зависит от того, сколько вы вычисляете в представлении (фильтрация / сортировка) по сравнению с тем, что у вас уже есть в модели (предварительно отсортированные / предварительно отфильтрованные данные).
Одно важное замечание:
ngIf (в отличие от ngShow) обычно создает дочерние области, которые могут давать неожиданные результаты.
У меня была проблема, связанная с этим, и я потратил НАМНОГО времени, чтобы выяснить, что происходит.
(Моя директива записывала значения модели в неправильную область.)
Таким образом, чтобы сохранить ваши волосы, просто используйте ngShow, если вы не бежите слишком медленно.
Разница в производительности едва заметна в любом случае, и я пока не уверен, кому это выгодно без теста...
Если вы используете ng-show or ng-hide
контент (например, миниатюры с сервера) будет загружен независимо от значения выражения, но будет отображаться на основе значения выражения.
Если вы используете ng-if
содержимое будет загружено только в том случае, если выражение ng-if оценивается как truey.
Использование ng-if - хорошая идея в ситуации, когда вы собираетесь загружать данные или изображения с сервера и показывать их только в зависимости от взаимодействия с пользователем. Таким образом, загрузка страницы не будет заблокирована ненужными и интенсивными задачами.
ng-if на ng-include и на ng-controller будет иметь большое влияние на ng-include, он не будет загружать необходимую частичку и не будет обрабатываться, если для ng-controller не установлено значение true, он не будет загружать контроллер, если флаг не установлен истина, но проблема в том, что когда флаг становится ложным в ng, если он удаляется из DOM, когда флаг возвращается в истинное значение, он перезагружает DOM, в этом случае ng-show лучше, на один раз лучше показывает ng-if