การรับค่า input จาก user ใน Angular App เบื้องต้น

เขียนเมื่อ 7 ปีก่อน โดย Ninenik Narkdee
template variable angular angular event input

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ template variable angular angular event input

ดูแล้ว 15,010 ครั้ง


สำหรับเนื้อหาในตอนนี้ เรามาดูตัวอย่างเกี่ยวกับการรับค่า input จาก user 
เช่น เมื่อ user ทำการคลิกลิ้งค์ กดปุ่ม หรือการกรอกข้อมูลลงใน textbox เป็นต้น 
ซึ่งการกระทำหรือ action ต่างๆ นี้เรียกว่า event
 

การเชื่อมกับ event 

เราสามารถใช้รูปแบบการเชื่อม event ใน Angular เพื่อทำงานกับทุก HTML DOM events ใดๆ ได้
โดย HTML DOM events ก็คือทุกๆ การกระทำที่เกิดกับ HTML elelment ต่างๆ เช่น onclick, onfucus,
onkeyup, onkeydown ดูข้อมูลเกี่ยวกับ DOM events เพิ่มเติมได้ที่ 
 
 
การเชิ่อม DOM event ในรูปแบบของ Angular event สามารถกำหนดโดยให้ชื่อ event อยู่ในวงเล็บ
แล้วกำหนดให้มีค่าเท่ากับฟังก์ชั่นหรือคำสั่งที่ต้องการ ซึ่งเรียกว่า template statement 
อยู่ในเครื่องหมาย ( "" ) ในลักษณะรูปแบบดังนี้
 

(ชื่อ event)="ฟังก์ชั่นหรือคำสั่ง หรือที่เรียกว่า template statement"

 

ตัวอย่าง

 
<button (click)="onClickMe()">Click me!</button>
 
(click) ที่อยูีทางฝั่งด้านซ้ายของเครืองหมาย = เป็นการกำหนด event click ให้กับ ปุ่ม ซึ่งเป็น
target ของการเชื่อม ส่วนข้อความที่อยู่ฝั่งขวาของเครื่องหมาย = ที่อยู่ในเครื่องหมาย " " เรียกว่า
template statement ทำหน้าที่ตอบสนองการทำงานของ event click โดยจะไปทำการเรียก method
(คำสั่งหรือการทำงาน) ที่ชื่อ onClickMe ภายใน component ให้ทำงาน
 

ดูภาพตัวอย่างประกอบ


 

 
 
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <button (click)="onClickMe()">Click me!</button>
    {{clickMessage}} 
  `,
})
export class AppComponent  { 

  clickMessage:string;

  constructor(){
    this.clickMessage = '';
  }

  onClickMe() {
    this.clickMessage = 'You are my hero!';
  }

}
 
จากโค้ด เมื่อทำการคลิกที่ปุ่ม Click me! จะมีการดักจับ event click และถ้า user 
ทำการ click ที่ปุ่มดังกล่าว คำสั่ง onClickMe() ก็จะถูกเรียกให้ทำงาน โดยผลลัพธ์จากโค้ด
ตัวอย่างคือ จะแสดงข้อความ 'You are my hero' ใน template ตรงตำแหน่งที่มีการแทรกค่า
จากตัวแปร clickMessage ในรูปแบบ {{clickMessage}} ดังรูป
 
 

 
 
 
 

การรับค่าจาก user ด้วย $event object

DOM events จะรับข้อมูลที่อาจจะนำไปใช้งานร่วมกับ component ในส่วนนี้จะแสดง
ให้เห็นการเชื่อม event keyup กับ input box เพื่อรับค่าที่ user กรอกเข้ามา 
ทุกๆ ครั้งหลังจากเคาะแป้นพิมพ์
 
โค้ดด้านล่าง จะเป็นลักษณะ input box ดักจับ event keyup แล้วทำการส่งค่า $event object เข้าใป
ในส่วนจัดการ event ของ component
 
 

 
 
 
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
  <input (keyup)="onKey($event)">
  <p>{{values}}</p>
  `,
})
export class AppComponent  { 

  values:string;

  constructor(){
    this.values = '';
  }

  onKey(event: any) { // without type info
    console.log(event);
    this.values += event.target.value + ' | ';
  }

}
 
เมื่อ user กดและปล่อยแป้นพิมพ์ จะเกิด keyup event แล้ว Angular จะเตรียม DOM event object
ที่สัมพันธ์กันไว้ให้ในตัวแปรชื่อ $event ซึ่งจากตัวอย่างโค้ดจะทำการส่งเป็นค่า parameter เข้าไปใน
คำสั่ง onKey() ใน component
 
ค่า property ของ $event object จะแตกต่างกันไปขึ้นกับชนิดของ DOM event นั้นๆ เช่น ใน mouse
event ก็จะมีข้อมูลที่แตกต่างจาก event จาก keyup keydown ใน input box  
 
โดยมาตรฐานทั่วไปแล้ว DOM event object จะมี target property เสมอ เพื่ออ้างอิง element นั้นๆ
กับ event ที่เกิดขึ้น ในกรณีตัวอย่างโค้ดด้านบน target เป็น <input> element และ 
event.target.value ก็คือ ค่าปัจจุบันที่ส่งกลับมาของ element นั้น
 
ทุกครั้งหลังจากมีการเรียกใช้คำสั่ง onKey() ก็จะทำการต่อท้ายข้อมูลจาก input box ไว้ใน component
property ที่ชื่อว่า values โดยใช้ (|) เป็นตัวแบ่ง การแสดงข้อมูลจากการแทรก component property
ที่เขื่อ  values ใน {{values}} จะแสดงค่าที่ต่อๆ รวมกันของ input box ที่เปลี่ยนแปลง 
 
สมมติว่า user กรอกตัวอักษร "abc" แล้ว กดปุ่ม backspace เพื่อลบรายการที่ละตัว ก็จะได้ผลลัพธ์
ดังรูปด้านล่าง
 
 

 
 
และถ้าเราเปลี่ยนจาก event.target.value เป็น event.key ซึ่งหมายถึง ชื่อของปุ่มนั้น
ค่าต่อๆรวมกันออกมา ตัวการกระทำสมมติที่จะเกิดขึ้นด้านบน ก็จะได้เป็น

 
a | b | c | backspace | backspace | backspace |
 
 

ประเภทของ $event

จากตัวอย่างด้านบน เป็นแบบกำหนด $event เป็นประเภทอะไรก็ได้ โดยใช้คำว่า any ซึ่งไม่มีการระบุ
ประเภทข้อมูล 
 
ที่นี้เรามาลองดูตัวอย่างการเขียนคำสั่งใหม่ โดยมีการกำหนดประเภทของ event เข้าไป
 
  onKey(event: KeyboardEvent) { // with type info
    console.log(event);
    this.values += (<HTMLInputElement>event.target).value + ' | ';
  }
 
 
จะเห็นว่า $event มีการระบุประเภทเป็น KeyobardEvent  
เนื่องจากไม่ใช่ element ทุกตัวที่จะมี value property ดังนั้นจึงสนใจ target ที่เป็น input element
 
 

การส่งค่าตัวแปร $event เป็นวิธีปฏิบัติที่ไม่ชัดเจน

การส่งตัวแปร event พบว่าเกิดข้อขัดแย้งอย่างมีนัยะในการส่งผ่าน DOM event เข้าไปใน medthod 
โดย component มีรายละเอียดของ template ที่ต้องพิจารณามากอยู่แล้ว ไม่สามารถ
ที่จะทำการแยกข้อมูลที่ไม่รู้จักได้ มากกกว่านั้นมันควรจะเป็นเพียงตัวแปลง HTML 
ซึ่งแบ่งแยกความสำคัญออกเป็นส่วนของ template (ส่วนที่แสดงให้ user เห็น) และ 
component (ส่วนที่จัดการข้อมูลจาก user) 
 
ดังนั้นการที่จะใช้ $event object ผ่านค่าเข้าไปใน method แล้วใช้ property ของ event นั้นๆ ระบุ 
target เป้าหมายที่ต้องการนำข้อมูลมาใช้งาน อย่างตัวอย่างที่กล่าวมาข้างต้น จึงยังไม่ใช่วิธีที่เหมาะสม
ในหัวข้อถัดไป เราจะมาดูวิธีการใช้งาน template variable ในการแก้ปัญหานี้
 
 

การรับค่าจาก user โดยอ้างอิงจาก template variable

อีกวิธีหนึ่งที่ใช้ในการรับค่าจาก user ก็คือการใช้งาน template variable โดยที่ตัวแปรนี้ให้เข้า
ถึง element ได้โดยตรงภายใน template 
การประกาศตัวแปร template variable ทำได้โดยการกำหนดชื่อตัวแปรแล้วให้มีเครื่องหมาย # นำหน้า
 
ดูตัวอย่างการกำหนดตัวแปร template variable ตามโค้ดด้านล่างประกอบ
 
 

 
 
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <input #box (keyup)="onKey(box.value)">
    <p>{{values}}</p>  
  `,
})
export class AppComponent  { 
  values:string;

  constructor(){
    this.values = '';
  }
  
  onKey(value: string) {
    this.values += value + ' | ';
  }

}
 
 
ตัวแปร template variable มีชื่อว่า box ซึ่งมีเครื่องหมาย # นำหน้า โดยมีการประกาศไว้ใน
<input> element ซึ่งชื่อตัวแปร box จะเป็นการอ้างอิงถึง input elelment หรือก็คือ target 
ของ template variable ก็คือตัวของมันเอง ดังนั้นการจะอ้างค่าของ <input> element นั้น
เราก็เพียงแค่เรียกใช้โดยการระบุ property เพิ่มเข้าไป อย่างตัวอย่าง เราต้องการค่าของ <input>
element เราก็จะอ้างอิงผ่านตัวแปร box.value แบบนี้เป็นต้น
 
จะเห็นว่าการใช้ template variable จะเป็นวิธีที่ง่ายกว่าการใช้วิธีส่งค่าตัวแปร $event เข้าไปแล้ว
หา target ตามหัวข้อที่ผ่านมา
 
 

การรับค่าเมื่อผู้ใช้กดปุ่ม Enter

ใน Angular จะมีวิธีการกรองค่า key event โดยสามารถระบุได้ว่าเป็นการกดปุ่ม Enter ซึ่งถ้าเราใช้
วิธีการปกติ ก็คือทำการตรวจจับ $event.keyCode แล้วเช็คว่าเป็นปุ่ม Enter หรือไม่ 
แต่ใน Angular เราสามารถทำดังนี้ได้ ดูรูปภาพโค้ดตัวอย่างประกอบ
 
 

 
 
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <input #box (keyup.enter)="onEnter(box.value)">
    <p>{{value}}</p>
  `,
})
export class AppComponent  { 
  value:string;

  constructor(){
    this.value = '';
  }

  onEnter(value: string) {
    this.value = value;
  }

}
 
จะเห็นว่ามีการใช้ (keyup.enter) ซึ่งเป็นรูปแบบของการกรอง event โดยเมื่อเกิด event keyup
ให้ดักจับ event เฉพาะที่เป็นกรณีกดปุ่ม Enter เท่านั้น ดูตัวอย่างผลลัพธ์ประกอบ
 
 

 
 
ทีนี้เรามาดูตัวอย่างโค้ดกรณีกำหนด event ตัวอย่างถูกนำมาใช้งานร่วมกันใน app 
 
 

 
 
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <input #sport
    (keyup.enter)="addSport(sport.value)"
    (blur)="addSport(sport.value); sport.value='' ">
    <button (click)="addSport(sport.value)">Add</button>
    <ul>
      <li *ngFor="let sport of sports">
        {{sport}}
      </li>
    </ul>
  `,
})
export class AppComponent  { 
  sports:string[];

  constructor(){
    this.sports = ['Football','Tennis','Bowling'];
  }

  addSport(sport: string) {
    if (sport) {
      this.sports.push(sport);
    }
  }  

}
 
ในตัวอย่างโค้ด จะแสดง input box ให้กรอกชื่อ sport ที่ต้องการเพิ่ม
โดยมี event อยู่ 3 อันคือ (keyup.enter) (blur) และ (click) โดยเมื่อกรอกรายชื่อกีฬา
ที่ต้องการเพิ่ม แล้วเกิด event ใดๆ ใน 3 event ข้างต้น ค่าของข้อมูลที่กรอก ก็จะถูกส่งไป
ในคำสั่ง addSport() และในคำสั่ง addSport() จะรับค่า parameter จากตัวแปร sport ที่เป็น
ประเภท string ซึ่งถ้ามีค่า ก็จะนำค่านั้นไป เพิ่มเข้าไปตัวแปร sports ซึ่งเป็นตัวแปร array
แล้วเมื่อมีค่าเพิ่มกัน รายการก็จะถูกเพิ่มเข้าไปใน <li> วนลูปแสดงออกมาดังรูปตัวอย่างผลลัพธ์
ด้านล่าง เมื่อเราทำการเพิ่ม Table tennis เข้าไป
 
 

 
 

ข้อสังเกต

การใช้ template variabel เพื่อระบุ element - ตัวแปร sport ที่เป็น template variable นั้น
จะอ้างอิงถึง <input> element ที่เป็น input box แต่สังเกตว่า เราสามารถเรียกใช้ตัวแปรนี้จาก
<button> นั้นคือเราสามารถอ้างอิงได้จาก element ใดๆ ที่อยู่ใน selector <my-app> ได้
 
ส่งค่าข้อมูล ไม่ได้ส่ง element - จะเห็นว่าแทนที่จะส่งค่า element ที่ชื่อ sport เข้าไปในคำสั่ง addSport()
แต่ใช่วิธีส่งค่าของข้อมูลโดยใช้ sport.value เข้าไปในคำสั่ง addSprot() แทน
 
ใช้รูปแบบคำสั่งแบบง่าย - ดูที่ blur event มีการใช้คำสั่ง JavaScript 2 คำสั่ง อันแรกคือคำสั่งเรียกใช้งาน
addSport() และคำสั่งที่สองคือ sport.value='' ล้างค่า <input> box หลังจากเพิ่มรายการเรียบร้อยแล้ว
 

เราได้รู้จักพื้นฐานเกี่ยวกับการรับค่าจาก user และการตอบสนองต่อ event ต่างๆ ในบื้องต้นแล้ว
ซึ่งเทคนิคเหล่านี้จะมีประโยชน์สำหรับเป็นแนวทางตัวอย่าง แต่ยังไม่ใช้วิธีที่เหมาะสมสำหรับนำไปใช้
ในกรณีที่มี input จำนวนมากๆ ดังนั้นเราจะได้ศึกษาเกี่ยวกับ การเชื่อมความสัมพันธ์แบบ Two-way 
หรือแบบไปกลับ ซึ่งจะมีลักษณะเรียบง่ายและกระชับ รอติดตามตอนต่อไป

 


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ



อ่านต่อที่บทความ













URL สำหรับอ้างอิง





คำแนะนำ และการใช้งาน

สมาชิก กรุณา ล็อกอินเข้าระบบ เพื่อตั้งคำถามใหม่ หรือ ตอบคำถาม สมาชิกใหม่ สมัครสมาชิกได้ที่ สมัครสมาชิก


  • ถาม-ตอบ กรุณา ล็อกอินเข้าระบบ
  • เปลี่ยน


    ( หรือ เข้าใช้งานผ่าน Social Login )







เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ