Angular7中父组件控制子组件菜单图标显隐及DOM类获取问题
嘿,我来帮你搞定Angular7里父组件控制子组件图标的问题,顺便解答你关于DOM操作的疑问~
实现父组件控制子组件菜单图标显示/隐藏(推荐方式:数据驱动)
Angular的核心思想是数据驱动视图,所以不推荐直接操作DOM,最好用组件间通信的方式来实现需求。具体步骤如下:
1. 给子组件(menu.component)添加输入属性
在menu.component.ts中定义一个@Input()属性,用来接收父组件传递的显示状态:
import { Component, Input } from '@angular/core'; @Component({ selector: 'sv-menu', templateUrl: './menu.component.html' }) export class MenuComponent { // 接收父组件传递的图标显示状态,默认隐藏 @Input() showBellIcon: boolean = false; emitOpenMenu() { // 你的原有逻辑 } }
2. 修改子组件模板绑定状态
把menu.component.html中铃铛图标的hidden属性改成绑定到我们定义的输入属性:
<div class="menu-top" (click)="emitOpenMenu()"> <div class="hamburgher-content"> <i class="fas fa-bars"></i> </div> <div> <i class="icon icon-sv-logo"></i> </div> <div> <!-- 用[hidden]绑定showBellIcon的反向值,showBellIcon为true时显示,false时隐藏 --> <i class="fas fa-bell" [hidden]="!showBellIcon" [routerLink]="'notifications'"></i> </div> </div>
3. 父组件(app.component)管理状态并传递给子组件
在app.component.ts中定义一个变量来控制图标的显示状态,然后在逻辑中修改它:
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { showMenuBool = true; showFab = true; showUp = true; // 控制铃铛图标的显示状态 showBellIcon: boolean = true; // 你的原有逻辑 someFunction(scanData: any) { if (scanData === null) { this.showBellIcon = false; // 隐藏子组件的铃铛图标 } else { this.showBellIcon = true; // 显示子组件的铃铛图标 } } openMenu() { /* 原有逻辑 */ } openScanDialog() { /* 原有逻辑 */ } gotoTop(target: any) { /* 原有逻辑 */ } RoutesChanged() { /* 原有逻辑 */ } }
4. 父组件模板传递属性给子组件
在app.component.html中给<sv-menu>添加[showBellIcon]属性绑定:
<mat-sidenav-content> <div #target></div> <div *ngIf="showMenuBool"> <!-- 把父组件的showBellIcon传递给子组件 --> <sv-menu (openMenuOutput)="openMenu()" [showBellIcon]="showBellIcon"></sv-menu> </div> <div style="margin-top:60px;"> <div class="fab-scan" *ngIf="showFab"> <button mat-fab color="primary" (click)="openScanDialog()"><i class="fas fa-barcode"></i></button> </div> <div class="fab-up" *ngIf="showUp"> <button mat-fab color="primary" (click)="gotoTop(target)"><i class="fas fa-arrow-up"></i></button> </div> <router-outlet (activate)="RoutesChanged()"></router-outlet> </div> </mat-sidenav-content>
关于Angular中通过DOM获取元素类的问题
答案是可以,但非常不推荐。Angular的设计理念就是让你通过数据来控制视图,直接操作DOM会打破这种数据驱动的模式,导致代码难以维护、容易出现bug(比如视图更新不同步)。
如果实在有特殊场景需要操作DOM,Angular提供了ViewChild和Renderer2来安全地操作:
示例(不推荐,仅作了解)
- 在子组件模板给图标加模板引用:
<i #bellIcon class="fas fa-bell" hidden="true" [routerLink]="'notifications'"></i>
- 在子组件类中获取元素并操作:
import { Component, ViewChild, ElementRef, Renderer2 } from '@angular/core'; @Component({ selector: 'sv-menu', templateUrl: './menu.component.html' }) export class MenuComponent { @ViewChild('bellIcon') bellIcon: ElementRef; constructor(private renderer: Renderer2) {} // 可以写一个方法来控制显示隐藏,父组件通过@Output或者服务调用这个方法 toggleBellIcon(show: boolean) { this.renderer.setProperty(this.bellIcon.nativeElement, 'hidden', !show); // 或者修改类:this.renderer.addClass(this.bellIcon.nativeElement, 'hidden'); } }
但再次强调,尽量用第一种数据驱动的方式实现,这才是Angular的正确打开方式,尤其你作为新手,养成好的编码习惯很重要~
内容的提问来源于stack exchange,提问作者Mr. Developer
相关产品推荐
相关产品推荐

