Яка різниця між ng-if і ng-show / ng-hid


427

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

Чи є різниця, яку я маю пам’ятати, вибираючи використовувати те чи інше?

Відповіді:


521

ng Якщо

У 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>

ngПокажіть

У ngShowдирективі показує або приховує даний HTML елемент на основі виразу , надане ngShowатрибут. Елемент відображається або приховується, видаляючи або додаючи ng-hideклас CSS до елемента. Клас .ng-hideCSS заздалегідь визначений у AngularJS і встановлює жодний стиль відображення (використовуючи !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клас classатрибуту CSS додається до атрибуту елемента, що призводить до його приховання. Коли true, то ng-hideклас CSS видаляються з елемента викликає елемент не з'являтися приховано.


31
Підказка: Видаляючи сам HTML-елемент із ng-ifмоделлю, доданий користувачем ng-model, більше не існує.
mrzmyr

3
@CodeHater Я успішно використовував ng-if над ng-show / ng-hid на сторінці, яка б інакше мала великий купол. Здавалося, зробити сторінку відчувати себе швидше, але аж ніяк не наукового аналізу.
Ед Спенсер

Частина, з якою у мене виникають проблеми з повним розумінням, полягає в тому, як / чому, коли у вас є об'єкт у моделі, data.inputвін працює ... але в dataсамоті в моделі не працює. @CodeHater
Марк Пешак - Trilon.io

7
@mcpDESIGNS ngIfстворює нову область застосування, тому, дивлячись на приклад вище вкладеного ngModel, створила б нову dataмодель, навіть незважаючи на те, що модель з тим самим іменем існує в батьківській області. Але коли ви використовуєте крапкові позначення, ви змушуєте JS шукати прототип ланцюга області. Тож якщо воно не знайде значення у поточній області, воно спробує шукати його у батьківській області тощо. Деякі інші директиви , які створюють різні сфери є ngInclude, ngRepeat. Сподіваюся, це зрозуміло зараз. :)
ЗавждиALearner

3
Який з них краще для продуктивності? Я думаю, що ng-show та ng-hid не так?
tom10271

97

Можливо, цікавим моментом є різниця між пріоритетами між обома.

Наскільки я можу сказати, директива ng-if має один із найвищих (якщо не найвищий) пріоритет усіх кутових директив. Що означає: вона запуститься ПЕРШИМО перед усіма іншими директивами з нижчим пріоритетом. Те, що він працює ПЕРШИЙ, означає, що ефективно, елемент видаляється перед тим, як будь-які внутрішні директиви будуть оброблені. Або принаймні: саме з цього я роблю.

Я спостерігав і використовував це в інтерфейсі, який будую для свого поточного замовника. Весь інтерфейс досить сильно упакований, і він мав ng-show та ng-приховування по всьому. Щоб не вдаватися до занадто багато деталей, але я створив загальний компонент, яким можна керувати за допомогою конфігурації JSON, тому мені довелося зробити деякий перемикання всередині шаблону. Існує присутність ng-повторів, а всередині ng-повторення показана таблиця, в якій присутня безліч ng-шоу, ng-шкур і навіть ng-перемикачів. Вони хотіли показати принаймні 50 повторів у списку, що призведе до того, щоб було вирішено більш-менш 1500-2000 директив. Я перевірив код, і Java Bakend + користувальницький JS на передній панелі займе близько 150 мс для обробки даних, і тоді Angular пережовує їх за 2-3 секунди, перш ніж показувати. Клієнт не поскаржився, але я був вражений :-)

У своєму пошуку я натрапив на директиву ng-if. Тепер, можливо, найкраще зазначити, що на момент створення цього інтерфейсу не було ng - якщо воно було доступне. Оскільки ng-show і ng-hid мали функції в них, які повертали булеві, я міг легко замінити їх усі ng-if. Тим самим всі внутрішні директиви, здавалося, більше не оцінювалися. Це означало, що я повернувся до приблизно третини всіх директив, що оцінюються, і, таким чином, інтерфейс прискорився приблизно до 500 мс - час завантаження на 1 сек. (Я не можу визначити точні секунди)

Зверніть увагу: той факт, що директиви не оцінюються, є освіченою здогадкою про те, що відбувається внизу.

Отже, на мою думку: якщо вам потрібен елемент, який повинен бути присутнім на сторінці (тобто для перевірки елемента, або будь-якого іншого), а просто бути прихованим, використовуйте ng-show / ng-hid. У всіх інших випадках використовуйте ng-if.


1
Так, я думаю, це мета ng-if: скоротити час обробки. Ця директива існує точно не лише завдяки деяким псевдоселекторам CSS. Гарний пост! +1
Bartłomiej Zalewski

36

ng-ifДиректива видаляє вміст сторінки і ng-show/ng-hideвикористовує CSS displayвластивість змісту приховати.

Це корисно, якщо ви хочете використовувати :first-childта :last-childпсевдоселектори для стилю.


що ви маєте на увазі, використовуючи селектор: first і: last?
Стефан Ролланд


16

@EdSpencer правильний. Якщо у вас багато елементів, і ви використовуєте ng-if, щоб лише інстанціювати відповідні, ви економите ресурси. @CodeHater також дещо правильний, якщо ви збираєтесь видаляти та показувати елемент дуже часто, приховування його замість видалення може підвищити продуктивність.

Основний випадок використання, який я вважаю для ng-if, - це те, що він дозволяє мені чітко перевірити та усунути елемент, якщо вміст є незаконним. Наприклад, я міг би посилатись на змінну назви нульового зображення, і це призведе до помилки, але якщо я ng-if і перевіряю, чи немає, це все добре. Якби я робив ng-шоу, помилка все-таки виникла б.


7

Одним важливим, що слід зазначити про ng-if і ng-show, є те, що при використанні елементів управління краще використовувати, ng-ifоскільки він повністю видаляє елемент з dom.

Ця різниця важлива, оскільки якщо створити поле для введення, required="true"а потім встановити ng-show="false"його приховати, Chrome видасть таку помилку, коли користувач намагається надіслати форму:

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

Причина поля поля введення є, і це так, requiredале оскільки він прихований, Chrome не може зосередитися на ньому. Це може буквально порушити ваш код, оскільки ця помилка зупиняє виконання сценарію. Тож будьте обережні!


Це справжній факт, якщо ви використовуєте контрольні форми для перевірки, тоді ви будете страждати сильно, якщо будете використовувати ng-show / ng-hid. І якщо у вас є кілька прихованих розділів / показуйте на основі вираження. Тож якщо ви використовуєте ng-show / hid, елементи все ще будуть там, і перевірка провалиться, незважаючи на те, що вони не відображаються на екрані. так що ng-if вас врятують :)
NeverGiveUp161

5

@Gajus Kuizinas і @CodeHater є правильними. Ось я лише наводжу приклад. Поки ми працюємо з ng-if, якщо присвоєне значення false, то всі елементи html будуть видалені з DOM. а якщо присвоєне значення вірно, то елементи HTML будуть видимі на DOM. І область застосування буде різною порівняно з батьківською сферою. Але у випадку ng-show він просто покаже та приховає елементи на основі присвоєного значення. Але це завжди залишається в DOM. Змінюється лише видимість відповідно до призначеного значення.

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

Сподіваємось, цей приклад допоможе вам зрозуміти сфери застосування. Спробуйте дати помилкові значення ng-show і ng-if і перевірте DOM в консолі. Спробуйте ввести значення у поля введення та спостерігайте за різницею.

<!DOCTYPE html>

Привіт Плункер!

<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}}


2

Факт, що 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>

У першому списку on-clickподія, showзмінна, з інтернату / власного діапазону, змінюється, але ng-ifпереглядає іншу змінну із зовнішньої області з тим самим ім'ям, тому рішення не працює. У випадку ng-showми маємо єдину showзмінну, тому вона працює. Для виправлення першої спроби нам слід посилатися на showбатьківський / зовнішній обсяг через $parent.show.


1
  1. ng-if if false буде видаляти елементи з DOM. Це означає, що всі ваші події, директиви, приєднані до цих елементів, будуть втрачені. Наприклад, клацніть ng на одному з дочірніх елементів, коли ng-if оцінюється як false, цей елемент буде видалено з DOM і знову, коли це правда, він буде відтворений.

  2. ng-show / ng-hid не видаляє елементи з DOM. Він використовує стилі CSS (.ng-hid), щоб приховати / показати елементи. Таким чином ваші події, директиви, прикріплені до дітей, не будуть втрачені.

  3. ng-if створює дочірню область, тоді як ng-show / ng-hid не робить.


1

ng-show і ng-hid працюють протилежно. Але різниця між ng-hid або ng-show з ng-якщо є, якщо ми використовуємо ng-if, тоді елемент буде створений у dom, але з ng-hid / 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. 

0

Зауважимо, що зі мною сталося зараз: ng-show приховує вміст через css, так, але це призвело до дивних збоїв у діві, які повинні бути кнопками.

У мене була карта з двома кнопками внизу, і залежно від фактичного стану одна обмінюється на третю, наприклад кнопку редагування з новим записом. Використовуючи ng-show = false, щоб приховати ліву (присутня спочатку у файлі), сталося, що наступна кнопка виявилася правою межею поза карткою. ng-if виправляє це, не включаючи код взагалі. (Просто перевірте тут, чи є якісь приховані сюрпризи, які використовують ng-if замість ng-show)


0

ngIf робить маніпуляцію на DOM, видаляючи або відтворюючи елемент.

Тоді як ngShow застосовує правила css для приховування / показу речей.

У більшості випадків (не завжди) я б підсумував це так, якщо вам потрібно одноразово перевірити, щоб показати / приховати речі, використовувати ng-if, якщо вам потрібно показувати / приховувати речі на основі дій користувача на екрані (наприклад, зареєстровано Поставте прапорець, потім покажіть текстове поле, зніміть прапорець, потім прихойте текстове поле тощо), а потім використовуйтеng-show


-17

Одна цікава різниця в ng-if і ng-show:

БЕЗПЕКА

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

де, як і у випадку з ng-show, користувач може відкрити вікно елемента перевірки елементів і встановити його значення на TRUE.

І з вершиною, весь вміст, який мав бути прихований, відображається, що є порушенням безпеки. :)


27
Це надзвичайно слабка форма безпеки. Якщо вміст надається клієнтові сервером, ви повинні припустити, що користувач / зловмисник може отримати доступ до нього, незалежно від того, присутній він у DOM чи ні. Вся логіка авторизації повинна бути застосована сервером.
tlrobinson

подумайте про html, а не jsp ... тепер, якщо ви хочете забезпечити безпеку компонентів html .. тобто якщо ви хочете приховати деякі компоненти від користувача ... як би ви цього домоглися. І що на випадок, якщо ваша конфігурація буде розділена на сторону сервера для бекенда та клієнтську сторону для переднього кінця ..
Ashish_B
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.