อะไรคือสิ่งที่เทียบเท่า ngShow และ ngHide ใน Angular 2+?


570

ฉันมีองค์ประกอบหลายอย่างที่ฉันต้องการให้ปรากฏภายใต้เงื่อนไขบางประการ

ใน AngularJS ฉันจะเขียน

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

ฉันจะทำสิ่งนี้ใน Angular 2+ ได้อย่างไร


[hidden] = "! myVar" .. มันใช้งานได้ในเชิงมุม 2+
Pragati Dugar

คำตอบ:


950

เพียงผูกกับ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 VS [hidden]

*ngIfลบเนื้อหาออกจาก DOM อย่างมีประสิทธิภาพในขณะที่[hidden]แก้ไขdisplayคุณสมบัติและสั่งให้เบราว์เซอร์ไม่แสดงเนื้อหา แต่ DOM ยังคงมีเนื้อหาอยู่


21
ไม่แนะนำให้ใช้การซ่อนจริง angularjs.blogspot.com/2016/04/…
Sam

7
*ngIfอาจเป็นวิธีที่ถูกต้องในกรณีส่วนใหญ่ แต่บางครั้งคุณต้องการให้องค์ประกอบอยู่ที่นั่นซ่อนอยู่ด้วยสายตา สไตล์ CSS พร้อมความ[hidden]{display:none!important}ช่วยเหลือ ตัวอย่างเช่นวิธี Bootstrap ทำให้แน่ใจว่า[hidden]องค์ประกอบถูกซ่อนอยู่จริง ดู GitHub
CunningFatalist

คุณอาจประสบปัญหาบางอย่างเมื่อคุณใช้ (myStream | async) ไปป์ที่ด้านในของ * ng หากยังใช้ไปยัง (myStream | async) ไปป์
Pavel Blagodov

1
คุณคือผู้ช่วยให้รอดของฉัน! ใช้ * ng ถ้าจะรีเซ็ตตำแหน่ง DOM ไปด้านบน แต่ [ซ่อน] แก้ไขปัญหาของฉันและรักษาตำแหน่งไว้
Santosh

1
กรณีหนึ่งที่หนึ่งอาจต้องการใช้ [ซ่อน] มากกว่า * ngIf คือเมื่อคุณใช้ HostListener (และต้องการแยกเอกสารคลิก vs event.target) เมื่อพยายามแสดงและซ่อนองค์ประกอบ (เช่นเดียวกับ drop downs แบบกำหนดเอง)
akhouri

140

ใช้[hidden]คุณลักษณะ:

[hidden]="!myVar"

หรือคุณสามารถใช้ *ngIf

*ngIf="myVar"

นี่เป็นสองวิธีในการแสดง / ซ่อนองค์ประกอบ ข้อแตกต่างคือ: *ngIfจะลบองค์ประกอบออกจาก DOM ในขณะที่[hidden]จะบอกให้เบราว์เซอร์แสดง / ซ่อนองค์ประกอบโดยใช้displayคุณสมบัติCSS โดยการรักษาองค์ประกอบไว้ใน DOM


3
[hidden] กำลังเพิ่มเงื่อนไขให้กับแอตทริบิวต์ "hidden" ในองค์ประกอบ มันอาจเป็น [อะไรก็ได้] หรือ [ali] สิ่งสำคัญที่นี่คือการโหลดกฎ CSS ที่กล่าวถึงคุณลักษณะ "ซ่อน" จะต้องมีการแสดง: ไม่มี
กาเบรียล

5
โปรดจำไว้ว่า: * ngIf และ [ซ่อน] มีความแตกต่างพื้นฐาน ngIf จะไม่ประเมินเนื้อหาภายในบล็อก * ngIf จนกว่าเงื่อนไขจะเป็นจริง นี่เป็นสิ่งสำคัญอย่างยิ่งหากคุณใช้asyncไพพ์เนื่องจากการสมัครสมาชิกไปยังสิ่งที่สังเกตได้จะถูกเพิ่มหลังจากเงื่อนไขกลายเป็นจริง!
Dynalon

2
อีกสิ่งหนึ่งที่ควรคำนึงถึงคือ ng หากทำลายส่วนประกอบและจะต้องสร้างขึ้นใหม่ในขณะที่ [ซ่อน] จะทำให้มันมีชีวิตอยู่และอยู่ในความทรงจำ หากคุณมีองค์ประกอบที่ต้องใช้ทรัพยากรสูงมันอาจจะดีกว่าถ้าคุณซ่อนมันแทนที่จะทำลายมัน
Michael Kork

1
พวกเขาไม่เหมือนกัน
Kamuran Sönecek

36

ฉันพบว่าตัวเองอยู่ในสถานการณ์เดียวกันกับความแตกต่างกว่าในกรณีของฉันองค์ประกอบเป็นคอนเทนเนอร์แบบยืดหยุ่นหากไม่ใช่กรณีของคุณการทำงานที่ง่ายอาจเป็นไปได้

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

ในกรณีของฉันเนื่องจากเบราว์เซอร์จำนวนมากที่เราสนับสนุนยังคงต้องใช้คำนำหน้าผู้ขายเพื่อหลีกเลี่ยงปัญหาที่ฉันไปหาทางออกที่ง่ายอีก

[class.is-loading]="isLoading"

ที่ไหน CSS นั้นง่ายเหมือน

&.is-loading { display: none } 

เพื่อออกจากสถานะที่แสดงที่จัดการโดยคลาสเริ่มต้น


1
ใช้งานได้ดีกับ bootstrap 4 invalid-feedbackclass
Jess

25

ขออภัยฉันไม่เห็นด้วยกับการเชื่อมโยงกับสิ่งที่ซ่อนอยู่ซึ่งถือว่าไม่ปลอดภัยเมื่อใช้ Angular 2 นี่เป็นเพราะรูปแบบที่ซ่อนอยู่สามารถเขียนทับได้ง่ายตัวอย่างเช่นการใช้

display: flex;

วิธีที่แนะนำคือใช้ * ngIf ซึ่งปลอดภัยกว่า สำหรับรายละเอียดเพิ่มเติมโปรดดูบล็อกทางการของแองกูลาร์ 5 ข้อผิดพลาดที่ควรหลีกเลี่ยงกับมือใหม่ 2

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

12
ฉันคิดว่าเป็นความผิดพลาดหน้าใหม่ที่จะพูดบางสิ่งที่ไม่ดีก่อนที่จะทราบข้อกำหนดที่แน่นอน หากไม่ต้องการให้องค์ประกอบถูกลบและทำลายและเพิ่มและสร้างใหม่*ngIfเป็นตัวเลือกที่แย่ แต่คุณมีสิทธิ์ที่จะต้องพิจารณาผลที่ตามมาและการชี้ให้เห็นถึงข้อผิดพลาดนั้นเป็นความคิดที่ดีเสมอ
GünterZöchbauer

2
ฉันรู้คุณหมายถึงอะไร. มันไม่ใช่คำพูดของฉันเกี่ยวกับมันเป็นความผิดพลาดสามเณรมันมาจากบล็อกอย่างเป็นทางการของ Angular 2 ฉันไม่ได้ตั้งใจจะทำร้ายใคร ขอบคุณสำหรับการชี้ให้เห็นว่า
ทิมหง

9
ใช่ฉันไม่คิดngIfว่าจะตอบคำถามที่ถามมาอย่างแน่นอน <router-outlet>ฉันต้องการที่จะซ่อนเนื้อหาบางส่วนในหน้านั้นรวมถึงการที่ ถ้าฉันใช้ngIfฉันได้รับข้อผิดพลาดที่ไม่สามารถหาทางออกได้ ฉันต้องการเต้าเสียบที่ซ่อนอยู่จนกว่าข้อมูลของฉันจะโหลดไม่หายไปจนกว่าจะโหลดข้อมูลของฉัน
Jason Swett

ฉันเห็นด้วยกับคุณ แต่ปัญหาที่ฉันมีคือฉันต้องการที่จะแสดงแบบฟอร์มและใส่ค่าลงไปถ้าฉันใช้ * ng ถ้าฉันจะมีข้อผิดพลาดที่ไม่ได้กำหนดไว้และด้วยคุณสมบัติที่ซ่อนอยู่มันทำงานได้ดี
Hazem HASAN

@HazemHASAN แน่นอน ฉันเข้าใจ. วิธีแก้ปัญหามีเงื่อนไขเสมอ ในกรณีของคุณไม่แน่ใจว่าเป็นไปได้หรือไม่ที่จะตรวจสอบว่ามีแบบฟอร์มนั้นหรือไม่ก่อนที่คุณจะเรียกใช้รหัสอื่น ๆ มันคือทั้งหมดที่เกี่ยวกับการแลกเปลี่ยน คุณต้องการวิธีที่ปลอดภัยกว่าในการซ่อนฟอร์มซึ่งจะไม่ถูกชดเชยด้วยการจัดแต่งทรงผมอื่นในอนาคตโดยไม่ตั้งใจหรือไม่? หรือคุณต้องการให้มีความสะดวกในการไม่ตรวจสอบว่ามีฟอร์มอยู่หรือไม่
ทิมหง

4

หากกรณีของคุณคือรูปแบบที่แสดงไม่มีคุณยังสามารถใช้คำสั่ง ngStyle และปรับเปลี่ยนการแสดงผลโดยตรงฉันทำเช่นนั้นสำหรับ bootstrap DropDown the 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: คุณลักษณะบูลที่ฉันสลับทุกครั้งและขึ้นอยู่กับ 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 directive 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 อาจถูกตั้งค่าเป็นจริงหรือเท็จ


2
<div hidden="{{ myExpression }}">สิ่งนี้จะไม่ทำงานเนื่องจาก "myExpression" จะถูกแปลงเป็นสตริงที่จะแสดงใน html ทั้งสตริง "จริง" และ "เท็จ" เป็นความจริงดังนั้นมันจะถูกซ่อนอยู่เสมอ
Viprus



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>




1

สำหรับฉัน[hidden]=!varไม่เคยทำงาน

ดังนั้น, <div *ngIf="expression" style="display:none;">

และ <div *ngIf="expression">ให้ผลลัพธ์ที่ถูกต้องเสมอ


0

มีสองตัวอย่างในเอกสารเชิงมุม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


0

วิธีที่ดีที่สุดในการจัดการกับปัญหานี้โดยใช้ngIf เพราะสิ่งนี้ช่วยป้องกันไม่ให้องค์ประกอบนั้นแสดงผลในส่วนหน้า

หากคุณใช้[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-template


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>

หากต้องการเพิ่มไปยังshoulds - yous ควรยังเราคำนำหน้าเช่นดังนั้น[acmeShown]VS [shown]เพียง

เหตุผลหลักที่ฉันใช้shownคำสั่งแอตทริบิวต์สำหรับการแปลงรหัส AngularJS เป็น Angular - และ - เมื่อเนื้อหาที่ถูกซ่อนอยู่มีส่วนประกอบส่วนประกอบที่ทำให้ 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 ให้กับองค์ประกอบเท่านั้น
Gil Epshtain

ตัวอย่างยาวเกินไปและเจาะจงเกินไป
masterxilo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.