Коли надавати перевагу ng-if проти ng-show / ng-hid?


516

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

Чи є вказівки щодо вибору ng-ifнад ng-show/ ng-hideчи навпаки?


5
можливий дублікат того, яка різниця між ng-if і ng-show / ng-
hid

1
Не стосується мови дартса .
naXa

Відповіді:


703

Залежить від вашого випадку використання, але підсумуйте різницю:

  1. ng-ifвидалить елементи з DOM. Це означає, що всі ваші обробники або що-небудь ще, прикріплене до цих елементів, будуть втрачені. Наприклад, якщо ви прив'язали обробник кліків до одного з дочірніх елементів, коли його ng-ifоцінюється як "false", цей елемент буде видалено з DOM, і ваш обробник кліків більше не працюватиме, навіть після того, як ng-ifпізніше буде оцінено значення true та відобразить елемент. Вам потрібно буде знову приєднати обробник.
  2. ng-show/ng-hideне видаляє елементи з DOM. Він використовує стилі CSS для приховування / показу елементів (зверніть увагу: можливо, вам потрібно буде додати власні класи). Таким чином ваші обробники, які були прикріплені до дітей, не втратяться.
  3. ng-ifстворює дитячу сферу, поки ng-show/ng-hideцього не робить

Елементи, яких немає в DOM, мають менший вплив на ефективність, і ваш веб-додаток може виглядати швидшим у ng-ifпорівнянні з ng-show/ng-hide. На мій досвід, різниця незначна. Анімації можливі при використанні обох ng-show/ng-hideі ng-if, з прикладами для обох у кутовій документації.

Зрештою, питання, на яке потрібно відповісти, полягає в тому, чи можете ви видалити елемент з DOM чи ні?


19
Ви можете використовувати анімацію CSS3 за допомогою ng-if. Перевірте абзац Анімації та приклад у документах . Також із ng-hide/ng-showселекторами css подобається :first-childабо :nth-childне працює належним чином, оскільки приховані елементи також будуть враховані.
Łukasz Wojciechowski

4
Анімаційна послуга у angular.dart порівняно нова. На момент написання цього повідомлення було недоступно.
markovuksanovic

44
Перша точка - це не проблема, якщо ви використовуєте директиви (наприклад, ng-click) для прив’язки обробників, як і належить.
Кевін К.

9
Крім того, ng-ifстворює новий діапазон, а ng-showні.
мартін

8
Слід також зазначити, що додавання та видалення елементів з DOM може спричинити за собою високі показники продуктивності, якщо робити це часто.
Кевін К.

130

Дивіться тут для CodePen , який демонструє різницю в тому , як нг-якщо / нг-шоу роботу, DOM-навхрест.

@markovuksanovic добре відповів на питання. Але я б підійшов до цього з іншої точки зору: я б завжди використовував ng-ifі отримував ці елементи з DOM, якщо тільки:

  1. тобі чомусь потрібні прив'язки даних і $watch-ее до ваших елементів, щоб вони залишалися активними, поки вони непомітні. Форми можуть бути хорошим випадком для цього, якщо ви хочете мати можливість перевірити дійсність на входах, які наразі не видно, щоб визначити, чи є ціла форма дійсною.
  2. Ви використовуєте деяку справді складну логіку стану з обробниками умовних подій, як згадувалося вище. Це означає , що якщо ви виявите вручну приєднання та від'єднання обробників, таких, що ви втрачаєте важливий стан при використанні ng-if, запитайте себе, чи буде цей стан краще представлений у моделі даних, і обробники, які умовно застосовуються директивами всякий раз елемент надається. По-іншому, наявність / відсутність обробників є формою даних про стан. Дістаньте ці дані з DOM і перетворіть у модель. Наявність / відсутність обробників слід визначати за даними, і таким чином легко відтворити.

Кутовий написаний дуже добре. Це швидко, враховуючи, що це робить. Але те, що він робить - це ціла купа магії, яка робить важкі речі (наприклад, двостороння прив'язка даних) виглядати тривіально просто. Зробити все те, що виглядає легко, тягне за собою деяку ефективність роботи. Можливо, ви будете шоковані, зрозумівши, скільки сотень чи тисяч разів функція сеттера оцінюється під час $digestциклу на купі DOM, на яку ніхто навіть не дивиться. І тоді ти розумієш, що у тебе є десятки чи сотні невидимих ​​елементів, які роблять те саме ...

Настільні комп’ютери дійсно можуть бути досить потужними, щоб відобразити більшість проблем щодо швидкості виконання JS. Але якщо ви розвиваєтеся для мобільних пристроїв, використовуйте ng-якщо, коли це можливо, по-людськи, це може бути безпроблемним. Швидкість JS все ще має значення для мобільних процесорів. Використання ng-if - це дуже простий спосіб отримати потенційно значну оптимізацію за дуже і дуже низькою вартістю.


6
Дуже приємне доповнення до вищезгаданої відповіді. Дається з хорошим контекстом, який також допомагає приймати рішення. Дякую.
Шон

1
ng-showможе бути корисним, коли у вас є, скажіть, вкладки, у яких є багато вмісту, на який потрібен час для візуалізації. Після першого візуалізації переміщення між вкладками буде миттєвим, тоді як ng-ifвимагатиме повторного відображення, прив'язки подій тощо. Мінусом, як ви кажете, є створення годинників, що виконуються у фоновому режимі. Кутовий відчайдушно потребуєng-ifshowwatch
найвище

53

З мого досвіду:

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 призведе до величезної різниці в тому, як ви пишете код свого контролера.


5
Це величезна правда! ng-якщо не обов'язково робить ваш фронтленд швидшим. Це залежить від ваших потреб. Насправді це може бути навпаки, якщо ви використовуєте в неправильній ситуації.
Тіаго С. С Вентура

1
Але, на мою думку, як ng-if не відображається на DOM, то це швидко порівняно з ng-show / hid. я помиляюся, будь ласка, дозвольте мені виправити цю точку.
Pardeep Jain

1
ng-якщо було б швидше, якщо він оціниться як false, оскільки, як ви кажете, нічого не потрібно вставляти в DOM. Але, якщо це правда, тоді у вас є накладні витрати на вставлення - можливо, досить складного - елемента в DOM.
Мауг каже, що повернемо Моніку

"2) ng-if створить / знищить область, коли вона буде оцінена як true / false. Якщо у вас є контролер, приєднаний до ng-if, цей код контролера буде виконуватися щоразу"
Red Pea

35

Відповідь не проста:

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

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

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

  • ng-if : Якщо навпаки елементи, ймовірно, не відображаються (рідкісні), просто будуйте їх і знищуйте їх у режимі реального часу, особливо якщо їх вміст дорого отримати (обчислення / сортування / фільтрування, зображення, генеровані зображення). Це ідеально підходить для рідкісних або «на вимогу» елементів, це економить пам’ять з точки зору не заповнення DOM, але може коштувати багато обчислень (створення / знищення елементів) та пропускної здатності (отримання віддаленого вмісту). Це також залежить від того, скільки ви обчислюєте в представленні (фільтрування / сортування) та того, що у вас вже є в моделі (попередньо відсортовані / попередньо відфільтровані дані).


2
Інші відповіді на технічні факти. Цей для мудрості. Ви чітко побудували нетривіальні кутові програми, сер! +1
найвищий

Ця проблема виходить за рамки кутової, вона є фундаментальною проблемою в інформатиці, є момент, коли один метод є більш ефективним, ніж інший. Зазвичай це може бути знайдено через деякий бенчмаркінг. Таким чином, ви навіть можете переключитися між одним методом на інший залежно від кількості предметів ... Подібна тема: math.stackexchange.com/questions/1632739/…
Крістоф Руссі

12

Одна важлива примітка:

ngIf (на відміну від ngShow) зазвичай створює дочірні області, які можуть призвести до несподіваних результатів.

У мене виникла проблема, пов’язана з цим, і я витратив багато часу, щоб з'ясувати, що відбувається.

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

Отже, для збереження волосся просто використовуйте ngShow, якщо ви не працюєте занадто повільно.

Різниця у виконанні ледве не помітна, і я ще не впевнений у тому, хто прихильний, без тесту ...


8
Використання $parent.scopevarприв'язки даних у межах ngIf дозволить виправити такі речі, як проблеми, пов’язані з дітьми,
meconroy

2
Це не зовсім вірно (коментар оригіналу @ user2173353, тобто). Якщо ви будете дотримуватися належних практик, ви не потрапите в біду. Це досить основне правило: "якщо немає крапки, ти робиш це неправильно". Дивіться тут демонстрацію того, як це працює: bit.ly/1SPv4wL . Ще одна чудова посилання (див. Помилку №2): bit.ly/1QfFeWd > (Моя директива записувала свої модельні значення в неправильну область застосування.) Це результат не дотримання вищевказаної практики.
piotr.d

1
@ piotr.d Ви маєте рацію, але це не те, на що початківцю, можливо, потрібно буде зосередитися, і є ще одна найкраща практика, яка говорить про те, що краще залишити покращення ефективності для кінця (особливо покращення продуктивності, яке може не бути поліпшенням у реальності) ). Я бачив, як люди ngIfвсюди вірять, що це покращить ефективність роботи. Це просто неправда, і не можна сказати, що найкраще, ngIfабо ngShowбез тесту чи глибокого аналізу в конкретному випадку. Тож я все-таки рекомендую забути про це ngIf, поки хтось не побачить погані показники чи не дізнається, що він робить
user2173353

2
Гарна думка. Але використання контролераAs робить це не проблемою. Дивіться, наприклад, прийом Джона Папи щодо контролерів AS і vm .
jsruok

4

ng-якщо на ng-include і на ng-контролері буде мати великий вплив на ng-include, він не завантажує необхідну часткову частину і не обробляє, якщо прапор не відповідає правильному ng-контролеру, він не завантажить контролер, якщо прапор не правда, але проблема полягає в тому, що коли прапор стає неправдивим у ng-якщо він видалиться з DOM, коли прапор повернеться істинним, він перезавантажить DOM у цьому випадку ng-show краще, на один раз покажіть ng-якщо краще


4

Якщо ви використовуєте ng-show or ng-hide вміст (наприклад, мініатюри з сервера), він буде завантажений незалежно від значення виразу, але відображатиметься на основі значення виразу.

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

Використання ng-if є хорошою ідеєю в ситуації, коли ви збираєтеся завантажити дані або зображення з сервера і показувати їх лише залежно від взаємодії користувачів. Таким чином завантаження вашої сторінки не буде заблоковано непотрібними великими інтенсивними завданнями.


Це особливо корисно, оскільки більшість браузерів завантажуватимуть зображення, навіть якщо CSS ховає свої DOM-контейнери. Зазвичай вони просто шукають srcатрибут imgтегу, коли він присутній, він завантажується!
Крістоф Руссі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.