Что эквивалентно ngShow и ngHide в Angular 2+?

У меня есть ряд элементов, которые я хочу видеть при определенных условиях.

В AngularJS я бы написал

<div ng-show="myVar">stuff</div>

Как я могу это сделать в Angular 2+?


person Mihai Răducanu    schedule 23.02.2016    source источник
comment
[hidden] =! myVar .. это работает в angular 2+   -  person Pragati Dugar    schedule 21.04.2020


Ответы (19)


Просто привяжите к свойству hidden

[hidden]="!myVar"

Смотрите также

проблемы

У hidden есть некоторые проблемы, потому что он может конфликтовать с CSS для свойства display.

Посмотрите, как some в пример Plunker не скрывается, потому что у него есть стиль

:host {display: block;}

установленный. (В других браузерах это может вести себя иначе - я тестировал с Chrome 50)

обходной путь

Вы можете исправить это, добавив

[hidden] { display: none !important;}

К глобальному стилю в index.html.

еще одна ловушка

hidden="false"
hidden="{{false}}"
hidden="{{isHidden}}" // isHidden = false;

такие же, как

hidden="true"

и не будет показывать элемент.

hidden="false" присвоит строку "false", которая считается правдивой.
Только значение false или удаление атрибута фактически сделает элемент видимым.

Использование {{}} также преобразует выражение в строку и не будет работать должным образом.

Только привязка с [] будет работать должным образом, потому что этому false присвоено значение false вместо "false".

*ngIf против [hidden]

*ngIf эффективно удаляет свое содержимое из DOM, в то время как [hidden] изменяет свойство display и только указывает браузеру не отображать содержимое, но DOM все еще содержит его.

person Günter Zöchbauer    schedule 23.02.2016
comment
*ngIf может быть правильным способом в большинстве случаев, но иногда вы действительно хотите, чтобы элемент был там, визуально скрытый. Помогает стиль CSS с [hidden]{display:none!important}. Так, например, Bootstrap обеспечивает скрытие [hidden] элементов. См. GitHub - person CunningFatalist; 01.03.2017
comment
Вы можете столкнуться с проблемой при использовании канала (myStream | async) внутри * ngIf, который также использует канал (myStream | async) - person Pavel Blagodov; 26.09.2017
comment
ты мой спаситель! использование * ngIf сбросит позицию DOM наверх, но [скрытый] решил мою проблему и сохранил позицию. - person Santosh; 08.12.2017
comment
@ GünterZöchbauer Я чувствую, что привык к чему-то вроде * ngShow в документах angular.io, когда я начал следовать angular 4. но я могу подтвердить, что сейчас такой вещи нет, и скрытое - единственное решение. Несколько месяцев назад я сам искал * ngShow и обнаружил, что сейчас такого нет, либо используйте скрытую, либо создайте настраиваемую директиву, если хотите более настраиваемый контроль над этим. - person Saif; 20.01.2019
comment
Вы могли попасть на Angular 1 документацию тогда, когда нашли ее. - person Günter Zöchbauer; 20.01.2019
comment
Один случай, когда вы можете захотеть использовать [hidden] вместо * ngIf, - это когда вы используете HostListener (и хотите различать клики по документу и event.target) при попытке показать и скрыть элементы (например, с настраиваемыми раскрывающимися списками) - person akhouri; 28.08.2019
comment
@Sam, ваш комментарий вводит в заблуждение. Да, у hidden есть свои особенности. Но согласно связанной статье неправильно говорить Using hidden is actually not recommended.. - person Sasuke Uchiha; 30.09.2020

Используйте атрибут [hidden]:

[hidden]="!myVar"

Или вы можете использовать *ngIf

*ngIf="myVar"

Это два способа показать / скрыть элемент. Единственная разница: *ngIf удалит элемент из DOM, а [hidden] скажет браузеру показать / скрыть элемент, используя свойство CSS display, сохраняя элемент в DOM.

person Ali Shahzad    schedule 23.02.2016
comment
[hidden] добавляет условно скрытый атрибут к элементу. Это также может быть [что угодно] или [Али]. Здесь важно загрузить правило CSS, в котором должны отображаться скрытые атрибуты: none - person Gabriel; 05.08.2016
comment
Имейте в виду: * ngIf и [hidden] принципиально разные. ngIf не будет оценивать содержимое внутри блока * ngIf, пока условие не станет истинным. Это особенно важно, если вы используете канал async, поскольку подписка на наблюдаемый объект будет добавлена ​​только после того, как условие станет истинным! - person Dynalon; 09.09.2016
comment
Еще одна вещь, которую следует принять во внимание, - это то, что * ngIf уничтожает компонент, и он должен быть создан заново, в то время как [hidden] сохраняет его живым и в памяти. Если у вас есть ресурсоемкий компонент, может быть предпочтительнее скрыть его, а не уничтожить. - person Michael Kork.; 16.11.2017
comment
это не одно и то же. - person Kamuran Sönecek; 18.08.2018
comment
Как уже говорилось, совсем не то же самое. Если компонент использует ngIf и результат ложный, он не будет отображаться вообще, поэтому любой код внутри компонента не будет выполняться, пока не будет выполнено условие ngIf. - person Daniel Dewhurst; 08.01.2021

Я нахожусь в той же ситуации с той разницей, что и в моем случае элемент был гибким контейнером. Если это не ваш случай, можно было бы легко обойтись

[style.display]="!isLoading ? 'block' : 'none'"

в моем случае из-за того, что многим браузерам, которые мы поддерживаем, по-прежнему нужен префикс поставщика, чтобы избежать проблем, я выбрал другое простое решение

[class.is-loading]="isLoading"

где тогда CSS прост как

&.is-loading { display: none } 

чтобы оставить отображаемое состояние, обрабатываемое классом по умолчанию.

person Valex    schedule 13.02.2017
comment
Это хорошо работает с классом начальной загрузки 4 invalid-feedback. - person Jess; 25.10.2018

Извините, я не согласен с привязкой к скрытому, которая считается небезопасной при использовании Angular 2. Это связано с тем, что скрытый стиль можно легко перезаписать, например, используя

display: flex;

Рекомендуемый подход - использовать * ngIf, что безопаснее. Для получения дополнительной информации, пожалуйста, обратитесь к официальному блогу Angular. 5 ошибок новичков, которых следует избегать с Angular 2

<div *ngIf="showGreeting">
   Hello, there!
</div>
person Tim Hong    schedule 28.10.2016
comment
Я считаю ошибкой новичка сказать, что что-то плохо, не зная точных требований. Если кто-то не хочет, чтобы элемент был удален, уничтожен, добавлен и воссоздан, *ngIf - плохой выбор. Но вы правы в том, что необходимо учитывать последствия, и всегда полезно указывать на подводные камни. - person Günter Zöchbauer; 25.11.2016
comment
Я знаю, что Вы имеете ввиду. Я не говорю, что это ошибка новичка, это взято из официального блога Angular 2. Я не хочу никого обидеть. Тем не менее, спасибо за указание. - person Tim Hong; 26.11.2016
comment
Да, я не думаю, что ngIf точно отвечает на этот вопрос. Я хочу скрыть некоторый контент на странице, содержащей <router-outlet>. Если я использую ngIf, я получаю сообщение об ошибке, что розетка не может быть найдена. Мне нужно, чтобы выход был скрытым, пока мои данные не загрузятся, а не отсутствующим, пока мои данные не загрузятся. - person Jason Swett; 28.11.2016
comment
Я согласен с вами, но проблема в том, что я хочу показать форму и поместить в нее значения, если я использую * ng, если у меня будет ошибка, что она не определена и со скрытым свойством она работает хорошо - person Hazem HASAN; 05.03.2019
comment
@HazemHASAN, конечно. Я понимаю. Решение всегда условное. В вашем случае не уверен, можно ли просто проверить, есть ли форма, прежде чем запускать для нее какой-либо другой код. Все дело в компромиссе. Вы хотите более безопасный способ скрыть форму, которая не будет случайно компенсирована другим стилем в будущем? Или вы предпочитаете не проверять, существует ли форма? - person Tim Hong; 06.03.2019

вот что сработало для меня:

<div [style.visibility]="showThis ? 'visible' : 'hidden'">blah</div>
person Alex    schedule 07.04.2020

<div [hidden]="myExpression">

myExpression может иметь значение true или false

person Niyaz    schedule 28.09.2016
comment
<div hidden="{{ myExpression }}"> Это не сработает, поскольку myExpression будет преобразован в строку, которая будет отображаться в HTML. И истинная, и ложная строка истинны, поэтому она всегда будет скрыта. - person Viprus; 06.09.2017

Для всех, кто сталкивается с этой проблемой, я решил это так.

import {Directive, ElementRef, Input, OnChanges, Renderer2} from "@angular/core";

@Directive({
  selector: '[hide]'
})
export class HideDirective implements OnChanges {
  @Input() hide: boolean;

  constructor(private renderer: Renderer2, private elRef: ElementRef) {}

  ngOnChanges() {
    if (this.hide) {
      this.renderer.setStyle(this.elRef.nativeElement, 'visibility', 'hidden');
    } else {
      this.renderer.setStyle(this.elRef.nativeElement, 'visibility', 'visible');
    }
  }
}

Я использовал 'visibility', потому что хотел сохранить пространство, занимаемое элементом. Если вы не хотите этого делать, вы можете просто использовать 'display' и установить для него значение 'none';

Вы можете привязать его к своему элементу html, динамически или нет.

<span hide="true"></span>

or

<span [hide]="anyBooleanExpression"></span>
person Anjil Dhamala    schedule 25.04.2018

Если ваш случай заключается в том, что стиль display none, вы также можете использовать директиву ngStyle и напрямую изменять отображение, я сделал это для начальной загрузки DropDown, UL на нем настроен на отображение none.

Поэтому я создал событие щелчка для «ручного» переключения UL для отображения

<div class="dropdown">
    <button class="btn btn-default" (click)="manualtoggle()"  id="dropdownMenu1" >
    Seleccione una Ubicación
    <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" [ngStyle]="{display:displayddl}">
        <li *ngFor="let object of Array" (click)="selectLocation(location)">{{object.Value}}</li>                                
     </ul>
 </div>    

Затем в компоненте у меня есть атрибут showDropDown: bool, который я переключаю каждый раз, и на основе int установите displayDDL для стиля следующим образом

showDropDown:boolean;
displayddl:string;
manualtoggle(){
    this.showDropDown = !this.showDropDown;
    this.displayddl = this.showDropDown ? "inline" : "none";
}
person Gary    schedule 08.08.2016

Используйте скрытый, как если бы вы связали любую модель с элементом управления, и укажите для него css:

HTML:

<input type="button" class="view form-control" value="View" [hidden]="true" />

CSS:

[hidden] {
   display: none;
}
person Sandip - Frontend Developer    schedule 28.09.2016

Согласно документации Angular 1 ngShow и ngHide, обе эти директивы добавляют стиль css display: none !important; к элементу в соответствии с условием этой директивы (для ngShow добавляет css для ложного значения, а для ngHide добавляет css для истинного значения).

Мы можем добиться этого с помощью директивы Angular 2 ngClass:

/* style.css */
.hide 
{
    display: none !important;
}

<!-- old angular1 ngShow -->
<div ng-show="ngShowVal"> I'm Angular1 ngShow... </div>

<!-- become new angular2 ngClass -->
<div [ngClass]="{ 'hide': !ngShowVal }"> I'm Angular2 ngShow... </div>

<!-- old angular2 ngHide -->
<div ng-hide="ngHideVal"> I'm Angular1 ngHide... </div>

<!-- become new angular2 ngClass -->
<div [ngClass]="{ 'hide': ngHideVal }"> I'm Angular2 ngHide... </div>

Обратите внимание, что для поведения show в Angular2 нам нужно добавить ! (not) перед ngShowVal, а для поведения hide в Angular2 нам не нужно добавлять ! (not) перед ngHideVal.

person Gil Epshtain    schedule 01.12.2016

Если вы используете Bootstrap, это очень просто:

<div [class.hidden]="myBooleanValue"></div>
person Gian Marco    schedule 22.03.2017
comment
В начальной загрузке 4 использование [hidden] делает то же самое, поэтому я рекомендую [hidden] - person Vahid; 23.03.2018

в начальной загрузке 4.0 класс "d-none" = "display: none! important;"

<div [ngClass]="{'d-none': exp}"> </div>
person 63RMAN    schedule 07.03.2018

для меня [hidden]=!var никогда не работал.

So, <div *ngIf="expression" style="display:none;">

И <div *ngIf="expression"> Всегда давать правильные результаты.

person Priyanka Arora    schedule 21.06.2019

Лучший способ справиться с этой проблемой с помощью ngIf Поскольку это хорошо препятствует получению этого элемента от рендеринга во внешнем интерфейсе,

Если вы используете [hidden]="true" или стиль hide [style.display], он будет скрывать только элемент в интерфейсе, и кто-то может легко изменить значение и увидеть его. На мой взгляд, лучший способ скрыть элемент - ngIf

<div *ngIf="myVar">stuff</div>

а также, если у вас есть несколько элементов (также необходимо реализовать еще), вы можете использовать опцию <ng-template>

<ng-container *ngIf="myVar; then loadAdmin else loadMenu"></ng-container>
<ng-template #loadMenu>
     <div>loadMenu</div>
</ng-template>

<ng-template #loadAdmin>
     <div>loadAdmin</div>
</ng-template>  

образец кода ng-шаблона

person DeC    schedule 29.10.2019
comment
Я согласен с вами, предпочтительнее использовать * ngIf вместо скрытого по какой-то причине производительности для оптимизации DOM - person Rebai Ahmed; 14.07.2021

Моя проблема заключалась в отображении / скрытии таблицы матов при нажатии кнопки с использованием ‹ng-container * ngIf = myVar›. «Загрузка» таблицы была очень медленной: 300 записей за 2-3 секунды.

Данные загружаются с использованием подписки в ngOnInit (), доступны и готовы к использованию в шаблоне, однако «загрузка» таблицы в шаблоне становится все медленнее с увеличением количества строк.

Мое решение заключалось в замене * ngIf на:

<div [style.display]="activeSelected ? 'block' : 'none'">

. Теперь таблица загружается мгновенно при нажатии кнопки.

person T. Bulford    schedule 28.01.2021

Есть два примера в документах Angular https://angular.io/guide/structural-directives#why-remove-rather-than-hide

Вместо этого директива может скрыть нежелательный абзац, установив для его стиля отображения значение none.

<p [style.display]="'block'">
  Expression sets display to "block".
  This paragraph is visible.
</p>

<p [style.display]="'none'">
  Expression sets display to "none".
  This paragraph is hidden but still in the DOM.
</p>

Вы можете использовать [style.display] = "'block'" для замены ngShow и [style.display] = "'none'" для замены ngHide.

person koo    schedule 10.05.2019

Если вы просто хотите использовать симметричные директивы _1 _ / _ 2_, которые поставляются с AngularJS, я предлагаю написать директиву атрибутов для упрощения таких шаблонов (проверено с Angular 7):


import { Directive, Input, HostBinding } from '@angular/core';

@Directive({ selector: '[shown]' })
export class ShownDirective {
  @Input() public shown: boolean;

  @HostBinding('attr.hidden')
  public get attrHidden(): string | null {
    return this.shown ? null : 'hidden';
  }
}

Многие другие решения верны. Вы должны использовать *ngIf везде, где это возможно. Использование атрибута hidden может иметь неожиданные стили, но если вы не пишете компоненты для других, вы, вероятно, знаете, есть ли это. Итак, чтобы эта директива shown работала, вы также должны убедиться, что вы добавили:

[hidden]: {
  display: none !important;
}

к вашим глобальным стилям где-нибудь.

С ними вы можете использовать такую ​​директиву:

<div [shown]="myVar">stuff</div>

с симметричной (и противоположной) версией так:

<div [hidden]="myVar">stuff</div>

Чтобы добавить к следует - вы также должны использовать такой префикс, как [acmeShown], а не просто [shown].

Основная причина, по которой я использовал директиву атрибутов shown, - это преобразование кода AngularJS в Angular -AND-, когда скрытый контент содержит компоненты контейнера, которые вызывают циклические обходы XHR. Причина, по которой я не использую просто [hidden]="!myVar", заключается в том, что достаточно часто это более сложно, например: [hidden]="!(myVar || yourVar) && anotherVar" - yes I can invert that, but it is more error prone. [показано] `просто легче думать.

person nephiw    schedule 10.12.2019

У вас есть два варианта:

Первый вариант

[style.display]="!isShow ? 'block' : 'none'"

Второй вариант

myVarible может быть логическим

[hidden]="!myVarible"
person Naeem Bashir    schedule 23.03.2021

Чтобы скрыть и показать div при нажатии кнопки в угловом 6.

HTML-код

<button (click)="toggleElement()">FormatCell</button>
<div class="ruleOptionsPanel" *ngIf="isShow">
   <table>
      <tr>
         <td>Name</td>
         <td>Ram</td>
      </tr>
   </table>
</div>

Код AppComponent.ts

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
})
export class AppComponent{
   isShow=false;
   toggleElement():void
   {
      this.isShow = !this.isShow
   }
}

это работает для меня, и это способ заменить ng-hide и ng-show в angular2 +

person Manoj Gupta    schedule 30.08.2018
comment
Вы используете ngIf, который отличается от ngShow. NgIf удалит / добавит элемент из DOM. Это не то же самое, что ngShow / ngHide, который только добавляет / удаляет стили Css для элемента. - person Gil Epshtain; 28.01.2019
comment
Пример слишком длинный и конкретный. - person masterxilo; 18.06.2019