Angular - DOM Manipulation | You Don't Need Jquery
-
Bagi pengguna Angular, mungkin sudah pernah menggunakan ataupun pernah dengar apa itu
Renderer
. Fitur ini sudah muncul sejak Angular versi 4. Bagi kamu pengguna Angular 8/9, saatnya bermigrasi keRenderer2
. Alasannya bisa kalian baca disini: Renderer to Renderer2 migrationSebelum lebih jauh, kita harus fahami dlu apa itu DOM, DOM atau Document Object Model, adalah dokumen (HTML) yang dimodelkan dalam sebuah objek, simplenya DOM adalah keseluruhan dokumen html yang dibentuk saat web diload oleh browser pertama kali. Jadi dengan DOM HTML ini kita dapat melakukan berbagi manipulasi pada element HTML, seperti: get, add, change, add atau delete.
Jika kamu pengguna Angular yg sebelumnya terbiasa dengan Jquery, maka tidak menutup kemungkinan kamu akan memilih Jquery sebagai pilihan pertama jika ketemu case seperti ini (bisa jadi) , karena.. ya tentunya krn jquery sudah memanjakan penggunanya lewat API2nya dia. So, ini tidak recommended ya, kalo mau tau alasannya bisa baca disini: STOP TRYING TO USE JQUERY IN ANGULAR
Okey, di case kali ini kita akan langsung bermain dengan
Renderer2
.Membuat element
Jika di jquery untuk membuat element kamu bisa melakukannya seperti ini:
$("<div/>").appendTo("div#main");
cukup mudah bukan? . Nah, mulai sekarang klo bisa kurang-kurangin / tinggalkan cara pandang jquery ini ya, krn di Angular caranya cukup berbeda.Code:
export class CreateElComponent implements OnInit { constructor( private renderer: Renderer2, private hostElement: ElementRef, ) {} ngOnInit() { const createLabelEl = this.renderer.createElement('label'); const createInputEl = this.renderer.createElement('input'); this.renderer.setStyle(createLabelEl, 'display', 'block'); this.renderer.setAttribute(createInputEl, 'type', 'text'); this.renderer.appendChild(createLabelEl, createInputEl); this.renderer.appendChild(this.hostElement.nativeElement, createLabelEl); } }
Pada code diatas, proses pembuatan element dilakukan di
ngOnInit()
jdi ketika Angular sudah selesai membuat component. Kemudian terdapat beberapa function disana contohnyacreateElement()
yg fungsinya utk membuat element, lalusetStyle()
dansetAttribute()
untuk menambahkan style dan attribute di element tersebut, selengkapnya kamu bisa baca disini: Renderer2 Doc. Setelah komponen dibuat, maka komponen di append dengan komponen rootnya.Jadi simplenya,
Renderer2
ini tugasnya merender/menampilkan element yang sudah dibuat, kemudianElementRef
tugasnya sebagai component reference dariRenderer2
, contohnya: membuat element, select element, etc.Custom Directive - Add/Remove Class
Seperti yang dijelaskan sebelumnya, kamu bisa menggunakan
Renderer2
ini di custom directive@Directive({ selector: `custom-directive, [customDirective]`, host: { 'class': `custom-directive` } }) export class CustomDirective { constructor( private renderer: Renderer2, private hostElement: ElementRef ) {} isClicked = false; @HostListener('click', ['$event.target']) _onClick() { this.isClicked = !this.isClicked; switch (this.isClicked ) { case true: { this.renderer.addClass(this.hostElement.nativeElement.parentNode, 'isActive'); break; } case false: { this.renderer.removeClass(this.hostElement.nativeElement.parentNode, 'isActive'); break; } } } }
Pada directive
custom-directive
ini, ketika terdapat eventclick
, maka akan mentoggle sebuah class isActive, kamu bisa menggunakan fungsi@HostListener()
untuk menghandle events yang ada pada element directive ini.Selecting elements
Kadang kala kamu ingin memilih suatu element, misalnya by id, class, ataupun tagname. Kamu juga masih bisa menggunakan API2 yg ada seperti di vanilla js (not jquery)
export class SelectingElComponent implements OnInit, AfterViewInit { constructor( private renderer: Renderer2, private hostElement: ElementRef ) {} ngAfterViewInit(){ const findInputEl = this.hostElement.nativeElement.querySelector('input[type="checkbox"]'); const findAllBtnEl = this.hostElement.nativeElement.querySelectorAll('button'); const hasClass = this.hostElement.nativeElement.classList.contains('container'); console.group( findInputEl, findAllBtnEl, hasClass ); } ngOnInit(){ setTimeout(() => { // For alternative }, 1) } }
Catatan disini, jdi selain menggunakan
ngAfterViewInit()
lifecycle, kamu juga bisa menggunakansetTimeout()
sbg alternative untuk mendetect suatu element, karena kadang kala terdapat beberapa case dimana kita ingin mendetect suatu element selain dingAfterViewInit()
contohnya di constructor, jika tanpasetTimeout()
, tentunya outputnya akan undefined, karena fungsi dipanggil sebelum component/directive dirender.Thanks.
Pengumuman!
Untuk yang baru join, jangan lupa perkenalkan dirimu disini ya
Juga jangan lupa baca ketentuan penggunaan di forum ini. Rekan-rekan bisa lihat disini.
Buat yang penasaran alasan dibuatnya forum BaliJS ini silakan baca disini.