Подтвердить что ты не робот

В чем разница между ng-if и ng-show/ng-hide

Я пытаюсь понять разницу между ng-if и ng-show/ng-hide, но они выглядят одинаково для меня.

Есть ли разница, которую я должен иметь в виду, выбирая один или другой?

4b9b3361

Ответ 1

ngIf

Директива ngIf удаляет или воссоздает часть дерева DOM на основе выражения. Если выражение, присвоенное ngIf, оценивается как ложное значение, тогда элемент удаляется из DOM, в противном случае клон этого элемента снова вводится в DOM.

<!-- when $scope.myValue is truthy (element is restored) -->
<div ng-if="1"></div>

<!-- when $scope.myValue is falsy (element is removed) -->
<div ng-if="0"></div>

Когда элемент удаляется с помощью ngIf, его область уничтожается и создается новая область, когда элемент восстанавливается. Область, созданная в ngIf, наследует ее родительскую область с использованием прототипального наследования.

Если ngModel используется в ngIf для привязки к примитиву JavaScript, определенному в родительской области, любые изменения, внесенные в переменную в пределах дочерней области, не будут влиять на значение в родительской области, например.

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="data">
</div>        

Чтобы обойти эту ситуацию и обновить модель в родительской области изнутри дочерней области, используйте объект:

<input type="text" ng-model="data.input">
<div ng-if="true">
    <input type="text" ng-model="data.input">
</div>

Или переменная $parent для ссылки на объект родительской области:

<input type="text" ng-model="data">
<div ng-if="true">
    <input type="text" ng-model="$parent.data">
</div>

ngShow

Директива ngShow показывает или скрывает данный HTML-элемент на основе выражения, предоставленного атрибуту ngShow. Элемент отображается или скрывается удалением или добавлением класса ng-hide CSS в элемент. Класс CSS .ng-hide предопределен в AngularJS и устанавливает стиль отображения равным none (используя флаг !important).

<!-- when $scope.myValue is truthy (element is visible) -->
<div ng-show="1"></div>

<!-- when $scope.myValue is falsy (element is hidden) -->
<div ng-show="0" class="ng-hide"></div>

Когда выражение ngShow оценивается как false, тогда класс ng-hide CSS добавляется к атрибуту class элемента, что заставляет его скрываться. Когда true, класс ng-hide CSS удаляется из элемента, заставляя элемент не казаться скрытым.

Ответ 2

Возможно, интересный момент - разница между приоритетами между ними.

Насколько я могу судить, директива ng-if имеет один из самых высоких (если не самый высокий) приоритет всех директив Angular. Это означает: он будет запускать FIRST перед всеми другими директивами с более низким приоритетом. Тот факт, что он запускает FIRST, означает, что элемент эффективно удаляется до того, как будут обработаны все внутренние. Или, по крайней мере: это то, что я делаю.

Я наблюдал и использовал это в пользовательском интерфейсе, который я создаю для своего текущего клиента. Весь пользовательский интерфейс довольно сильно упакован, и на нем было ng-show и ng-hide. Не вдаваться в подробности, но я создал общий компонент, которым можно было управлять с помощью конфигурации JSON, поэтому мне пришлось сделать некоторые изменения внутри шаблона. Существует ng-repeat present, а внутри ng-repeat показана таблица, в которой много ng-show, ng-hides и даже ng-переключателей. Они хотели показать не менее 50 повторов в списке, что приведет к тому, что более или менее 1500-2000 директив будут разрешены. Я проверил код, а бэкэнд Java + пользовательский JS на передней панели занял около 150 мс для обработки данных, а затем Angular пережевал бы около 2-3 секунд, прежде чем отображать. Клиент не жаловался, но я был потрясен:-)

В моем поиске я наткнулся на директиву ng-if. Теперь, может быть, лучше всего указать на то, что при понимании этого пользовательского интерфейса не было ng-если оно доступно. Поскольку ng-show и ng-hide имели в них функции, которые возвращали логические значения, я мог бы легко заменить их на ng-if. Поступая таким образом, все внутренние директивы, похоже, уже не оценивались. Это означало, что я опустился примерно до трети всех оцениваемых директив, и, таким образом, пользовательский интерфейс ускорился примерно до 500 мс - 1 сек времени загрузки. (У меня нет способа определить точные секунды)

Обратите внимание: тот факт, что директивы не оцениваются, является просвещенным предположением о том, что происходит внизу.

Итак, на мой взгляд: если вам нужно, чтобы элемент присутствовал на странице (то есть: для проверки элемента или что-то еще), но просто скрывайте, используйте ng-show/ng-hide. Во всех остальных случаях используйте ng-if.

Ответ 3

Директива ng-if удаляет содержимое со страницы, а ng-show/ng-hide использует свойство CSS display, чтобы скрыть содержимое.

Это полезно, если вы хотите использовать псевдо-селектора :first-child и :last-child для стиля.

Ответ 4

@EdSpencer верен. Если у вас много элементов, и вы используете ng - если вы только создаете экземпляр соответствующих, вы сохраняете ресурсы. @CodeHater также несколько правилен, если вы собираетесь удалить и показать элемент очень часто, скрывая его, а не удаляя его, это может повысить производительность.

Основной случай использования, который я нахожу для ng-if, заключается в том, что он позволяет мне чисто проверять и исключать элемент, если содержимое является незаконным. Например, я мог бы ссылаться на переменную имени нулевого изображения, и это вызовет ошибку, но если я ng-if и проверьте, является ли оно нулевым, все это хорошо. Если я сделал ng-show, ошибка все равно будет срабатывать.

Ответ 5

Одна из важных замечаний о ng-if и ng-show заключается в том, что при использовании элементов управления формы лучше использовать ng-if, потому что он полностью удаляет элемент из dom.

Это различие важно, потому что, если вы создаете поле ввода с помощью required="true", а затем установите ng-show="false", чтобы скрыть его, Chrome выдает следующую ошибку, когда пользователь пытается отправить форму:

An invalid form control with name='' is not focusable.

Причиной является поле ввода, и оно required, но поскольку оно скрыто, Chrome не может сфокусироваться на нем. Это может буквально разорвать ваш код, так как эта ошибка останавливает выполнение script. Будьте осторожны!

Ответ 6

@Gajus Kuizinas и @CodeHater верны. Здесь я просто приведу пример. Пока мы работаем с ng-if, если назначенное значение ложно, то все элементы html будут удалены из DOM. и если назначенное значение истинно, то элементы html будут видны в DOM. И область будет отличаться по сравнению с родительской областью. Но в случае ng-show он просто покажет и спрячет элементы на основе назначенного значения. Но он всегда остается в DOM. Изменяется только видимость в соответствии с назначенным значением.

http://plnkr.co/edit/3G0V9ivUzzc8kpLb1OQn?p=preview

Надеюсь, этот пример поможет вам понять области. Попробуйте дать ложные значения ng-show и ng-if и проверить DOM в консоли. Попробуйте ввести значения в поля ввода и наблюдать разницу.

<!DOCTYPE html>

        

  

Привет, Plunker!

<input type="text" ng-model="data">
<div ng-show="true">
    <br/>ng-show=true :: <br/><input type="text" ng-model="data">
</div>
<div ng-if="true">
    <br/>ng-if=true :: <br/><input type="text" ng-model="data">
</div> 
{{data}}

Ответ 7

Факт, что директива ng-if, в отличие от ng-show, создает свою собственную область действия, приводит к интересной практической разнице:

angular.module('app', []).controller('ctrl', function($scope){
  $scope.delete = function(array, item){
    array.splice(array.indexOf(item), 1);
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app='app' ng-controller='ctrl'>
   <h4>ng-if:</h4>
   <ul ng-init='arr1 = [1,2,3]'>
      <li ng-repeat='x in arr1'>
        {{show}}
        <button ng-if='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-if='show' ng-click='delete(arr1, x)'>Yes {{show}}</button>
        <button ng-if='show' ng-click='show=!show'>No</button>
      </li>
   </ul>
   
   <h4>ng-show:</h4>
   <ul ng-init='arr2 = [1,2,3]'>
      <li ng-repeat='x in arr2'>
        {{show}}
        <button ng-show='!show' ng-click='show=!show'>Delete {{show}}</button>
        <button ng-show='show' ng-click='delete(arr2, x)'>Yes {{show}}</button>
        <button ng-show='show' ng-click='show=!show'>No</button>
      </li>
   </ul>
   
   <h4>ng-if with $parent:</h4>
    <ul ng-init='arr3 = [1,2,3]'>
      <li ng-repeat='item in arr3'>
        {{show}}
        <button ng-if='!show' ng-click='$parent.show=!$parent.show'>Delete {{$parent.show}}</button>
        <button ng-if='show' ng-click='delete(arr3, x)'>Yes {{$parent.show}}</button>
        <button ng-if='show' ng-click='$parent.show=!$parent.show'>No</button>
      </li>
   </ul>
</div>

Ответ 8

  • ng - если false приведет к удалению элементов из DOM. Это означает, что все ваши события, директивы, привязанные к этим элементам, будут потеряны. Например, ng-click для одного из дочерних элементов, когда ng-if оценивает значение false, этот элемент будет удален из DOM и снова, когда он верен, он воссоздается.

  • ng-show/ng-hide не удаляет элементы из DOM. Он использует стили CSS (.ng-hide), чтобы скрыть/показать элементы. Таким образом ваши события, директивы, прикрепленные к детям, не будут потеряны.

  • ng-if создает дочернюю область, пока ng-show/ng-hide не делает.

Ответ 9

Чтобы заметить, что случилось со мной сейчас: ng-show действительно скрывает содержимое через css, да, но это привело к странным сбоям в div, которые должны быть кнопками.

У меня была карта с двумя кнопками внизу и в зависимости от фактического состояния, которое обменивается с третьей кнопкой редактирования примера с новой записью. Используя ng-show = false, чтобы скрыть левый (присутствующий сначала в файле), оказалось, что следующая кнопка оказалась с правой границей вне карты. ng-if исправляет это, не включая код вообще. (Только что проверили здесь, если есть какие-то скрытые сюрпризы, используя ng-if вместо ng-show)

Ответ 10

ng-show и ng-hide работают в обратном порядке. Но разница между ng-hide или ng-show с ng-if есть, если мы используем ng-if, тогда элемент будет создан в dom, но с элементом ng-hide/ng-show будет полностью скрыт.

ng-show=true/ng-hide=false:
Element will be displayed

ng-show=false/ng-hide=true:
element will be hidden

ng-if =true
element will be created

ng-if= false
element will be created in the dom. 

Ответ 11

ng-show и ng-if получает условие и скрывает от представления элемент директивы в случае, если условие оценивается как false. Однако механики, которые они используют, чтобы скрыть представление, отличаются.

ng-show/ng-hide переключить внешний вид элемента, добавив экран CSS: none style.

а

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

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

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

Ответ 12

ngIf выполняет манипуляции с DOM, удаляя или воссоздавая элемент.

В то время как ngShow применяет правила css, чтобы скрыть/показать вещи.

В большинстве случаев (не всегда) я бы обобщил это так: если вам нужно одноразовую проверку, чтобы показать/скрыть вещи, используйте ng-if, если вам нужно показать/скрыть вещи на основе действий пользователя на экране (например, отметьте флажок, затем покажите текстовое поле, снимите флажок, затем скройте текстовое поле и т.д.), затем используйте ng-show

Ответ 13

Одно интересное различие в ng-if и ng-show:

Безопасность

Элементы DOM, присутствующие в блоке ng-if, не будут отображаться в случае его значения как false

где, как и в случае ng-show, пользователь может открыть окно Inspect Element и установить его значение TRUE.

И с воплем отображается все содержимое, предназначенное для скрытия, что является нарушением безопасности.:)