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


570

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

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

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

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


[скрыто] = "! myVar" .. это работает в угловых 2+
Прагати Дугар

Ответы:


951

Просто привязать к 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 все еще содержит его.


21
Использование скрытого на самом деле не рекомендуется. angularjs.blogspot.com/2016/04/…
Сэм

7
*ngIfв большинстве случаев может быть правильным, но иногда вы действительно хотите, чтобы элемент был там, визуально скрыт. Стиль CSS с [hidden]{display:none!important}подсказками. Вот, например, как Bootstrap гарантирует, что [hidden]элементы действительно скрыты. Смотрите GitHub
CunningFatalist

Вы можете столкнуться с некоторой проблемой, когда используете канал (myStream | async) внутри * ngIf, который также использует канал (myStream | async)
Павел Благодов

1
ты мой спаситель! использование * ngIf сбросит позицию DOM наверх, но [скрытый] решил мою проблему и сохранил позицию.
Сантош

1
Один из случаев, когда можно использовать [скрытый] поверх * ngIf, - это когда вы используете HostListener (и хотите различать клики документов по сравнению с event.target), когда пытаетесь показать и скрыть элементы (например, с помощью пользовательских выпадающих меню)
akhouri

141

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

[hidden]="!myVar"

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

*ngIf="myVar"

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


3
[скрытый] добавляет условно атрибут «скрытый» к элементу. Это также может быть [что угодно] или [Али]. Здесь важно загрузить CSS-правило, в котором упоминаются «скрытые» атрибуты: нет
Gabriel

5
Имейте в виду: * ngIf и [hidden] фундаментально различны. ngIf не будет оценивать содержимое внутри блока * ngIf, пока условие не станет истинным. Это особенно важно, если вы используете asyncканал, так как подписка на наблюдаемое будет добавлена ​​только после того, как условие станет истинным!
Диналон

2
Еще одна вещь, которую следует принять во внимание, это то, что * ngIf уничтожает компонент, и он должен быть воссоздан, в то время как [скрытый] сохраняет его живым и в памяти. Если у вас есть ресурсоемкий компонент, может быть предпочтительнее скрыть его, чем уничтожить
Майкл Корк.

1
они не одно и то же.
Камуран Сёнечек

36

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

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

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

[class.is-loading]="isLoading"

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

&.is-loading { display: none } 

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


1
Это хорошо работает с начальной загрузкой 4 invalid-feedbackкласса.
Джесс

25

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

display: flex;

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

<div *ngIf="showGreeting">
   Hello, there!
</div>

12
Я считаю ошибкой новичка говорить что-то плохое, прежде чем точно знать требования. Если кто-то не хочет, чтобы элемент был удален, уничтожен, добавлен и воссоздан, *ngIfплохой выбор. Но вы правы, что необходимо учитывать последствия, и указывать на подводные камни всегда хорошая идея.
Гюнтер Цохбауэр

2
Я знаю, что Вы имеете ввиду. Это не мое слово, это ошибка новичка, это взято из официального блога Angular 2. Я не хочу никого обидеть. Спасибо за указание, хотя.
Тим Хонг

9
Да, я не думаю ngIf, что точно отвечает на этот вопрос. Я хочу скрыть некоторый контент на странице, которая включает в себя <router-outlet>. Если я использую ngIf, я получаю ошибку, что он не может найти выход. Мне нужно, чтобы розетка была скрыта до тех пор, пока мои данные не загрузятся, а не исчезнет, пока мои данные не загрузятся.
Джейсон Светт

Я согласен с вами, но проблема в том, что я хочу показать форму и поместить в нее значения, если я использую * ngIf, если у меня будет ошибка, что она не определена и со скрытым свойством она работает хорошо
Hazem ГАСАНА

@HazemHASAN, конечно. Я понимаю. Решение всегда условно. В вашем случае, не уверены, что можно просто проверить, есть ли форма, прежде чем запускать какой-либо другой код против нее. Это все о компромиссе. Хотите более безопасный способ скрыть форму, которая не будет случайно смещена другим стилем в будущем? Или вы предпочитаете не проверять, существует ли форма?
Тим Хонг

4

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

Поэтому я создал событие щелчка для «ручного» переключения 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";
}

4

Согласно документации 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 нам нужно добавить !(не) перед ngShowVal, а для hideповедения в Angular2 нам не нужно добавлять !(не) перед ngHideVal.


4
<div [hidden]="myExpression">

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


2
<div hidden="{{ myExpression }}">Это не будет работать, так как «myExpression» будет преобразовано в строку, которая будет отображаться в html. И строка «true», и «false» являются правдивыми, поэтому они всегда будут скрыты
Viprus

3

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

<div [class.hidden]="myBooleanValue"></div>

3
В начальной загрузке 4 использование [hidden]делает то же самое, поэтому я рекомендую[hidden]
Vahid

3

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

<div [ngClass]="{'d-none': exp}"> </div>

3

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

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>

или

<span [hide]="anyBooleanExpression"></span>

2

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

HTML:

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

CSS:

[hidden] {
   display: none;
}

2

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

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


1

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

Так, <div *ngIf="expression" style="display:none;">

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


0

Есть два примера на англоязычных документах 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.


0

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

Если вы используете [hidden]="true"стиль или скрыть [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-шаблона


0

Если вы просто хотите использовать симметричные hidden/ shownдирективы, с которыми поставляется 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]vs just [shown].

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


-1

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

HTML-код

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

Компонент .ts Код

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

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

наслаждаться...

Спасибо


Вы используете ngIf, который отличается от ngShow. NgIf удалит / добавит элемент из DOM. Это не то же самое, что ngShow / ngHide, который будет только добавлять / удалять стили Css для элемента.
Джил Эпштейн

Пример слишком длинный и слишком конкретный.
masterxilo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.