2017-03-15 25 views
5

Tôi đang cố gắng thêm lớp sẽ thay đổi giao diện của nó (ví dụ: burger thành x), thành phần DOM trình kích hoạt trình đơn có phương pháp riêng để hiển thị trình đơn lớp phủ, nhưng tôi không thể tìm ra cách để làm điều đó.Góc 2 - Thêm lớp vào phần tử DOM khi nhấp vào

Dưới đây là những gì tôi có cho đến nay - điều này được gọi một phương thức bên ngoài cho menu chính nó:

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

Tôi mới vào góc 2. Làm thế nào là phải rèn luyện? Tôi có nên sử dụng số Renderer hay không, tại sao tôi nên sử dụng số Renderer? Và câu hỏi, vv


EDIT: Vấn đề với sự kiện nhấn tuyệt đối (chọn con, chứ không phải công ty mẹ) là chúng ta phải sử dụng một reference tag ghép nối với các @ViewChild trang trí như vậy:

@ViewChild('navTrigger') navTrigger: ElementRef; liên quan đến tham chiếu #navTrigger trong mẫu HTML.

Do đó:

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 –

Trả lời

8

Để thực hiện những gì bạn muốn, bạn sẽ cần phải sử dụng Renderer (tiêm nó vào các nhà xây dựng với private renderer: Renderer). Trình kết xuất cung cấp sự trừu tượng hóa trên các phần tử gốc và cung cấp một cách an toàn để tương tác với DOM.

Trong mẫu của bạn, bạn sẽ có thể làm điều gì đó như thế này:

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

này ghi lại sự kiện click và vượt qua nó để menuToggle chức năng.

Sau đó, trong thành phần của bạn, bạn sẽ có thể tương tác với DOM bằng cách sử dụng Renderer như thế này:

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

Chức năng chữ ký cho setElementClass, theo docssetElementClass(renderElement: any, className: string, isAdd: boolean) : void

Để đọc thêm trên Trình kết xuất, this is a good article on Medium. Khi nói về việc sử dụng ViewChild và truy cập vào DOM qua nativeElement so với sử dụng các Renderer, nó nói:

này hoạt động tốt (sử dụng nativeElement từ một ViewChild). Chúng tôi đang lấy phần tử đầu vào với sự trợ giúp của trình trang trí ViewChild và sau đó truy cập phần tử DOM gốc và gọi phương thức focus() trên đầu vào.

Vấn đề với cách tiếp cận này là khi chúng ta truy cập vào các yếu tố có nguồn gốc trực tiếp chúng tôi đang đưa ra lên trên DOM trừu tượng góc và bỏ lỡ cơ hội để có thể để thực hiện cũng trong môi trường không-DOM như: mẹ đẻ di động, máy tính để bàn gốc, nhân viên web hoặc hiển thị bên máy chủ.

Hãy nhớ rằng Góc là nền tảng và trình duyệt chỉ là một tùy chọn cho nơi chúng tôi có thể hiển thị ứng dụng của chúng tôi.

Hy vọng điều này sẽ hữu ích.

+0

Độ chính xác tâm-boggling trên câu trả lời. Tôi có một vấn đề nhỏ với điều này mặc dù, trong đánh dấu ' ' điều này đang được thêm vào phần tử con bên trong, không phải cho chủ sở hữu trực tiếp của lớp. Làm thế nào tôi có thể sửa lỗi này? – snkv

0

Tạo trường sao lưu trong thành phần rồi liên kết với ngClass và sử dụng biểu thức kiểu để thêm điều kiện lớp vào phần tử có điều kiện. Lưu ý sự kiện nhấp chuột nên được sử dụng để chuyển đổi trường sao lưu. ví dụ.

  1. Trong thành phần: openedBool: boolean = false;
  2. toggleOpenedBool() { openedBool = !openedBool; }
  3. Trong mẫu: <div (click)="toggleOpenedBool()" [ngClass]="{'opened': openedBool}"></div>
3

Kể từ câu trả lời của Tyler, mọi thứ đã thay đổi một chút. Renderer bị khấu hao và được thay thế bằng Renderer2. Trong Renderer 2, lớp setElementClass được thay thế bằng addClass. Và chức năng chữ ký mới cho addClass, theo docs được

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

Vì vậy, các cập nhật menuToggle chức năng nên đọc

menuToggle(event:any) { 
    this.renderer.addClass(event.target,"opened"); 
} 
Các vấn đề liên quan