我试图添加一个类,它将其外观(例如汉堡到x)改为菜单触发器DOM元素,它有自己的方法来显示叠加菜单,但我无法弄清楚如何做到这一点。
这是我到目前为止 - 这是调用菜单本身的外部方法:
import { Component, ElementRef, ViewChild, Renderer, AfterViewInit } from '@angular/core';
import { LayoutService } from 'app/core/services/layout.service';
@Component({
moduleId: module.id,
selector: 'header-main',
templateUrl: 'header-main.component.html',
})
export class HeaderMainComponent {
@ViewChild('nav-trigger') el: ElementRef;
constructor(private layoutService: LayoutService) { }
menuToggle() {
this.layoutService.mainMenuToggle();
this.el.nativeElement.classList.add('opened');
}
}
我是Angular 2的新手。这应该如何解决?我应该使用Renderer
,为什么我应该使用Renderer
?等问题
编辑:绝对点击事件(选择孩子,而不是父母)的问题是,我们必须使用与reference tag装饰器配对的
@ViewChild
,如下所示:
@ViewChild('navTrigger') navTrigger: ElementRef;
,它与HTML模板中的#navTrigger
引用有关。
因此:
export class HeaderMainComponent {
logoAlt = 'We Craft beautiful websites'; // Logo alt and title texts
@ViewChild('navTrigger') navTrigger: ElementRef;
constructor(private layoutService: LayoutService, private renderer: Renderer) { }
menuToggle(event: any) {
this.layoutService.mainMenuToggle();
this.renderer.setElementClass(this.navTrigger.nativeElement, 'opened', true);
}
}
要完成您想要的任务,您需要使用渲染器(使用private renderer: Renderer
将其注入构造函数中)。 Renderer提供了对原生元素的抽象,并提供了与DOM交互的安全方式。
在您的模板中,您应该可以执行以下操作:
<div (click)="menuToggle($event)"></div>
这将捕获click事件并将其传递给menuToggle
函数。
然后在您的组件中,您应该能够使用Renderer与DOM进行交互,如下所示:
menuToggle(event:any) {
this.renderer.setElementClass(event.target,"opened",true);
}
根据setElementClass
,docs的功能签名是setElementClass(renderElement: any, className: string, isAdd: boolean) : void
有关渲染器的进一步阅读,this is a good article on Medium。在讨论使用ViewChild
并通过nativeElement
访问DOM与使用Renderer
相比时,它说:
这工作正常(使用ViewChild中的nativeElement)。我们在ViewChild装饰器的帮助下抓取input元素,然后访问本机DOM元素并在输入上调用focus()方法。
这种方法的问题在于,当我们直接访问本机元素时,我们放弃了Angular的DOM抽象,错过了在非DOM环境中执行的机会,例如:native mobile,native desktop,web worker或服务器端渲染。
请记住,Angular是一个平台,浏览器只是我们可以渲染我们的应用程序的一个选项。
希望这可以帮助。
自Tyler回答以来,事情发生了一些变化。 Renderer
折旧并由Renderer2
取代。在Renderer 2
,类setElementClass
被addClass
取代。根据addClass
的说法,docs的新功能签名是
addClass(el: any, name: string): void
所以更新的menuToggle
函数应该读取
menuToggle(event:any) {
this.renderer.addClass(event.target,"opened");
}
在组件中创建一个支持字段,然后绑定到ngClass并使用typescript表达式有条件地将该类添加到该元素。请注意,应使用单击事件来切换支持字段。例如。
openedBool: boolean = false;
toggleOpenedBool() { openedBool = !openedBool; }
<div (click)="toggleOpenedBool()" [ngClass]="{'opened': openedBool}"></div>