2017-03-15 58 views
5

我试图添加一个类,它将改变它的外观(,例如汉堡到x),到一个菜单触发DOM元素,它有自己的方法来显示覆盖菜单,但我无法弄清楚如何做到这一点。Angular 2 - 在点击时向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'); 
    } 
} 

我是新来的角2.这是如何工作了呢?我应该使用Renderer,为什么我应该使用Renderer?等问题


编辑:用绝对click事件(选择子,不是父)的问题是,我们必须使用一个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); 
    } 
} 
+0

https://angular.io/docs/ts/latest/guide/template -syntax.html#!#ngClass –

回答

8

来完成你想要什么,你需要使用的渲染器(将其注入构造与private renderer: Renderer)。渲染器提供对本地元素的抽象,并提供了一种与DOM交互的安全方式。

在您的模板,你应该能够做这样的事情:

<div (click)="menuToggle($event)"></div> 

这捕获click事件,并把它传递给menuToggle功能。

然后在你的组件,你应该能够使用这样的渲染与DOM交互:

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

setElementClass函数签名,根据docssetElementClass(renderElement: any, className: string, isAdd: boolean) : void

进一步的阅读在Renderer上,this is a good article on Medium。在谈到使用ViewChild和访问DOM通过nativeElement与使用Renderer,它说:

也能正常工作(使用nativeElement从ViewChild)。我们使用ViewChild装饰器帮助获取输入元素,然后访问本地DOM元素,并在输入上调用focus()方法。

这种方法 的问题是,当我们直接访问本地元素,我们在 角的DOM抽象放弃和错过的机会,能够 在无-DOM环境下也执行如:本地移动, 原生桌面,网络工作者或服务器端渲染。

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

希望这会有所帮助。

+0

答案令人难以置信的精确度。我有一个小问题,虽然在标记' '这是被添加到内部子元素,而不是该类的直接所有者。我怎样才能解决这个问题? – snkv

3

由于泰勒的回答,事情已经改变了一点。 Renderer已折旧并由Renderer2取代。在Renderer 2中,类setElementClass被替换为addClass。并根据docsaddClass新功能的签名,是

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

所以更新menuToggle功能应该读

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