ChatGPT解决这个技术问题 Extra ChatGPT

Angular 2+ 中 ngShow 和 ngHide 的等价物是什么?

我有一些我希望在特定条件下可见的元素。

在 AngularJS 我会写

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

我怎样才能在 Angular 2+ 中做到这一点?

[hidden]="!myVar".. 这适用于 Angular 2+

G
Günter Zöchbauer

hidden 属性可用于此

[hidden]="!myVar"

也可以看看

https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden

问题

hidden 有一些问题,因为它可能与 display 属性的 CSS 冲突。

看看 Plunker example 中的 some 如何不会因为有样式而被隐藏

: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 仍包含它。


*ngIf 在大多数情况下可能是正确的方式,但有时您实际上希望一个元素存在,视觉上是隐藏的。带有 [hidden]{display:none!important} 的 CSS 样式会有所帮助。例如,这就是 Bootstrap 如何确保 [hidden] 元素实际上是隐藏的。 See GitHub
当您在 *ngIf 内部使用 (myStream | async) 管道时,您可能会遇到一些问题,该管道也使用 (myStream | async) 管道
你是我的救星!使用 *ngIf 会将 DOM 位置重置为顶部,但 [hidden] 解决了我的问题并保留了该位置。
一种可能想要在 *ngIf 上使用 [hidden] 的情况是,当您使用 HostListener(并且想要区分文档点击与 event.target)时,在尝试显示和隐藏元素时(例如使用自定义下拉菜单)
@Sam,您的评论具有误导性。是的,hidden 有一些特殊性。但是根据链接的文章,说Using hidden is actually not recommended.是错误的。
A
Ali Shahzad

使用 [hidden] 属性:

[hidden]="!myVar"

或者您可以使用 *ngIf

*ngIf="myVar"

这是显示/隐藏元素的两种方式。唯一的区别是:*ngIf 将从 DOM 中删除元素,而 [hidden] 将通过将元素保留在 DOM 中来告诉浏览器使用 CSS display 属性显示/隐藏元素。


[hidden] 正在向元素添加条件属性“隐藏”。它也可以是 [whatever] 或 [ali]。这里重要的是加载一个提到“隐藏”属性的 CSS 规则必须是 display:none
请记住:*ngIf 和 [hidden] 是根本不同的。在条件为真之前,ngIf 不会评估 *ngIf 块内的内容。如果您使用 async 管道,这一点尤其重要,因为只有在条件变为 true 后才会添加对 observable 的订阅!
要考虑的另一件事是 *ngIf 会破坏组件并且必须重新创建它,而 [hidden] 使其保持活动状态并保留在内存中。如果您有一个资源密集型组件,最好隐藏它而不是销毁它
他们不是一回事。
如前所述,根本不一样。如果组件正在使用 ngIf 并且结果为 false,则根本不会呈现它,因此组件内的任何代码在满足 ngIf 条件之前都不会运行。
V
Valex

我发现自己处于与我的情况不同的情况相同的情况下,元素是一个弹性容器。如果不是你的情况,一个简单的解决方法可能是

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

在我的情况下,由于我们支持的许多浏览器仍然需要供应商前缀以避免出现问题,我选择了另一个简单的解决方案

[class.is-loading]="isLoading"

那么CSS很简单

&.is-loading { display: none } 

离开然后由默认类处理的显示状态。


这适用于 bootstrap 4 invalid-feedback 类。
T
Tim Hong

抱歉,我不同意绑定到 hidden ,这在使用 Angular 2 时被认为是不安全的。这是因为隐藏样式可以很容易地被覆盖,例如使用

display: flex;

推荐的方法是使用更安全的 *ngIf。更多详细信息,请参考 Angular 官方博客。 5 Rookie Mistakes to Avoid with Angular 2

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

我认为在了解确切要求之前说某事不好是一个新手错误。如果不想移除和销毁、添加和重新创建元素,则 *ngIf 是一个糟糕的选择。但是你是对的,需要考虑后果,指出陷阱总是一个好主意。
我知道你的意思。这不是我的话,这是一个新手错误,它来自 Angular 2 官方博客。我无意冒犯任何人。不过,感谢您指出。
是的,我认为 ngIf 并不能准确回答这个问题。我想在包含 <router-outlet> 的页面上隐藏一些内容。如果我使用 ngIf,我会收到找不到插座的错误。我需要将插座 隐藏 直到我的数据加载,而不是 absent 直到我的数据加载。
我同意你的观点,但是我遇到的问题是如果我使用 *ngIf 我想显示一个表单并将值放入其中
@HazemHASAN,当然。我明白。解决方案总是有条件的。在您的情况下,不确定是否可以在针对它运行任何其他代码之前检查表单是否存在。这都是关于权衡的。您是否想要一种更安全的方式来隐藏将来不会被其他样式意外抵消的表单?或者您更喜欢方便不检查表单是否存在?
A
Alex

这对我有用:

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

m
masterxilo
<div [hidden]="myExpression">

myExpression 可以设置为 true 或 false


<div hidden="{{ myExpression }}"> 这不起作用,因为“myExpression”将被转换为要在 html 中呈现的字符串。字符串 "true" 和 "false" 都是真值,所以它会一直隐藏
@Viprus 不是在找你,但我以前在这里看到过这种对“真实”一词的误用。如果 CSS 选择器是 [hidden],并且该属性存在于 HTML 中并且具有值,则将应用该规则。在这种情况下,真实性并不重要,因为它不是 JS。
A
Anjil Dhamala

对于其他偶然发现这个问题的人,这就是我完成它的方式。

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>

这似乎是最“Angular”的方式。
G
Gil Epshtain

根据 ngShowngHide 的 Angular 1 文档,这两个指令都根据该指令的条件将 css 样式 display: none !important; 添加到元素(对于 ngShow 添加了 false 值的 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>

请注意,对于 Angular2 中的 show 行为,我们需要在 ngShowVal 之前添加 !(不是),而对于 Angular2 中的 hide 行为,我们不需要需要添加 !(不是) 在 ngHideVal 之前。


G
Gary

如果您的情况是样式为无显示,您也可以使用 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";
}

S
Sandip - Frontend Developer

使用 hidden 就像您将任何模型与控件绑定并为其指定 css 一样:

HTML:

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

CSS:

[hidden] {
   display: none;
}

G
Gian Marco

如果你使用 Bootstrap 就这么简单:

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

在 bootstrap 4 中使用 [hidden] 做同样的事情,所以我推荐 [hidden]
6
63RMAN

在引导程序 4.0 中,类 "d-none" = "display: none!important;"

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

C
Chirag
<div [hidden]="flagValue">
---content---
</div>

G
Ganesh

对我来说,[hidden]=!var 从来没有奏效过。

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

而且,<div *ngIf="expression"> 始终给出正确的结果。


m
mahmoud elgml

使用 [ngStyle]

[ngStyle]="{'visibility': my-flag ? 'visible' : 'hidden'}"

T
T. Bulford

我的问题是使用 在单击按钮时显示/隐藏垫表。表的“加载”非常慢,2-3 秒内有 300 条记录。

数据是使用 ngOnInit() 中的订阅加载的,并且可以在模板中使用并准备好使用,但是随着行数的增加,模板中表格的“加载”变得越来越慢。

我的解决方案是将 *ngIf 替换为:

.现在,当单击按钮时,表格会立即加载。


D
DeC

使用 ngIf 处理此问题的最佳方法因为这将阻止该元素在前端呈现,

如果您使用 [hidden]="true" 或 style hide [style.display] 它只会隐藏前端的元素,并且有人可以更改它的值并轻松查看它,在我看来隐藏元素的最佳方法是 ngIf

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

如果您有多个元素(还需要实现 else),您可以使用 <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>  

sample ng-template code


我同意你的观点,出于某种性能原因,最好使用 *ngIf 而不是 hidden 来优化 DOM
k
koo

Angular 文档中有两个示例 https://angular.io/guide/structural-directives#why-remove-rather-than-hide

指令可以通过将其显示样式设置为无来隐藏不需要的段落。

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


n
nephiw

如果您只想使用 AngularJS 附带的对称 hidden/shown 指令,我建议您编写一个属性指令来简化模板,如下所示(使用 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>

要添加到 shoulds - 您还应该使用像 [acmeShown] 这样的前缀而不是 [shown]

我使用 shown 属性指令的主要原因是当隐藏的内容包含导致 XHR 往返的容器组件时,将 AngularJS 代码转换为 Angular -AND-。我不只使用 [hidden]="!myVar" 的原因是它经常比较复杂,例如:[hidden]="!(myVar || yourVar) && anotherVar" - yes I can invert that, but it is more error prone.[shown]` 更容易思考。


N
Naeem Bashir

你有两个选择:

第一个选项

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

第二种选择

myVarible 可以是布尔值

[hidden]="!myVarible"

I
IAfanasov

要在按钮上隐藏和显示 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
   }
}

这对我有用,它是一种在 angular2+ 中替换 ng-hide 和 ng-show 的方法


您正在使用 ngIf - 这与 ngShow 不同。 NgIf 将从 DOM 中删除/添加元素。这与 ngShow/ngHide 不同,后者只会向元素添加/删除 Css 样式。
这个例子太长而且太具体了。