Angular 2 - 单击时向DOM元素添加类

时间:2017-03-15 12:08:59

标签: angular

我正在尝试添加一个类,它会改变它的外观(例如汉堡到x )到一个菜单触发器DOM元素,它有自己的方法来显示叠加菜单,但我可以&# 39;弄清楚如何去做。

这是我到目前为止所做的 - 这是为菜单本身调用外部方法:

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?等问题

  

编辑:绝对点击事件(选择孩子,而不是父母)的问题是,我们必须使用与@ViewChild装饰者配对的 reference tag 作为这样:

@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);
    }
}

3 个答案:

答案 0 :(得分:16)

要完成您想要的任务,您需要使用渲染器(使用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的功能签名,docssetElementClass(renderElement: any, className: string, isAdd: boolean) : void

有关渲染器的进一步阅读,this is a good article on Medium。在讨论使用ViewChild并通过nativeElement访问DOM与使用Renderer相比时,它说:

  

这很好用(使用ViewChild中的nativeElement)。我们在帮助下抓住输入元素   ViewChild装饰器然后访问本机DOM元素和   在输入上调用focus()方法。

     

这种方法的问题   就是当我们直接访问本机元素时,我们就放弃了   Angular的DOM抽象和错失机会能够   也可以在非DOM环境中执行,例如:native mobile,   本机桌面,Web工作者或服务器端呈现。

     

请记住   Angular是一个平台,浏览器只是我们的一个选择   可以渲染我们的应用程序。

希望这有帮助。

答案 1 :(得分:6)

自Tyler回答以来,情况发生了一些变化。 Renderer已弃用,并由Renderer2替换。在Renderer 2中,班级setElementClassaddClass取代。根据{{​​3}},addClass的新功能签名是

addClass(el: any, name: string): void

因此更新后的menuToggle函数应为

menuToggle(event:any) {
    this.renderer.addClass(event.target,"opened");
}

答案 2 :(得分:0)

在组件中创建一个支持字段,然后绑定到ngClass并使用typescript表达式有条件地将该类添加到该元素。请注意,应使用单击事件来切换支持字段。例如。

  1. 在组件中:openedBool: boolean = false;
  2. toggleOpenedBool() { openedBool = !openedBool; }
  3. 在模板中:<div (click)="toggleOpenedBool()" [ngClass]="{'opened': openedBool}"></div>