การส่งค่าจาก Form ด้วย ngModel FormBuilder และ Template ใน Ionic

เขียนเมื่อ 6 ปีก่อน โดย Ninenik Narkdee
formbuilder ngmodel template ionic native

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

ดูแล้ว 10,193 ครั้ง


เนื้อหาต่อไปนี้ เราจะมาทบทวนรูปแบบการส่งค่าข้อมูลต่างๆ จากฟอร์มเพื่อนำไปใช้งาน ยกตัวอย่าง
เช่น การส่งค่าจากหน้า ล็อกอิน เพื่อเข้าสู่ระบบ หรือการส่งค่าฟอร์มจากหน้าสมัครสมาชิก เป็นต้น
เหตุที่ว่าเป็นการทบทวนก็เพราะ เนื้อหาการใช้งานการส่งข้อมูลจากฟอร์มนั้น หากเราศึกษาการใช้งาน
angular มาแต่ต้น ก็คงจะได้รู้จักวิธีการใช้งานไปบ้างแล้ว หรือสามารถกลับไปทบทวนเนื้อหาต่างๆ ย้อน
หลังได้ที่บนความตามลิ้งค์ด้านล่าง
    
 
ก่อนอื่น ให้เราทำการสร้าง หน้า page สำหรับใช้งานกันก่อน โดยในที่นี้ เราจะสร้างหน้า LoginPage ด้วยฟอร์มล็อกอิน
อย่างง่าย เริ่มต้นสร้าง page login ด้วยคำสั่ง ionic cli ดังนี้
 
ionic generate page login --no-module
 
เราจะได้ไฟล์ login.html login.scss และ login.ts จากนั้นกำหนดหน้าตาการแสดงของฟอร์มล็อกอินในไฟล์
login.html ดังนี้
 
ไฟล์ login.html
 
<ion-header>
    <ion-navbar color="danger">
        <button ion-button menuToggle>
            <ion-icon name="menu"></ion-icon>
          </button>    
      <ion-title>Login</ion-title>
    </ion-navbar>
  </ion-header>
   
  <ion-content padding>
    <div padding text-center>
      <h3>Please Log In</h3>
    </div>   
    <form>
      <ion-list>
        <ion-item>
          <ion-label floating>Username</ion-label>
          <ion-input type="text"></ion-input>
        </ion-item>
      
        <ion-item>
          <ion-label floating>Password</ion-label>
          <ion-input type="password"></ion-input>
        </ion-item>
      </ion-list>
      <div>
        <button type="submit" block ion-button color="danger">Login</button>
      </div>     
    </form>    
  </ion-content>
 
ต่อด้วยโค้ดเริ่มต้นไฟล์ login.ts ดังนี้
 
ไฟล์ login.ts
 
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';

@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {

  constructor(public navCtrl: NavController, public navParams: NavParams) {
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad LoginPage');
  }

}
 
เราจะได้หน้าตาของหน้าล็อกอินเริ่มต้นเป็นดังนี้
 
 

 
 
 
การทำงานของหน้าล็อกอินก็ง่าย คือเรากรอกข้อมูล username และ password แล้วเมื่อกดปุ่ม Login ก็ทำการ
ส่งข้อมูลจากฟอร์มไปใช้งาน โดยเราจะมีรูปแบบการส่งค่าจากฟอร์มไปใช้งานอยู่ 3 รูปแบบดังต่อไปนี้
 
  • ส่งข้อมูลจากฟอร์มผ่านการใช้งาน [(ngModel)] 
  • ส่งข้อมูลจากฟอร์มผ่าน Templates
  • ส่งข้อมูลจากฟอร์มผ่าน FormBuilder
 
 

ส่งข้อมูลจากฟอร์มผ่านการใช้งาน [(ngModel)] 

    การส่งค่าข้อมูลจากฟอร์ม โดยใช้การเชื่อมโยงข้อมูลด้วย ngModel เป็นรุปแบบบางส่วนของการใช้งาน 
Template Driven Form ใน angular     จะเหมาะกับข้อมูลที่มีจำนวนฟิลด์ไม่มาก ข้อดี ก็คือใช้งานง่าย
ไม่ยุ่งยาก แต่ข้อเสีย ก็จะมีในเรื่องของการจัดการข้อมูล เช่น การตรวจสอบข้อมูลก่อนส่ง ซึ่งอาจจะไม่รองรับ
การจัดการที่ซับซ้อนมากๆ ไม่ได้หรือไม่ดีพอ
    การใช้งาน ก็คือเราจะต้องทำการสร้างตัวแปรไว้ใน page component เพิ่มเชื่อมกับ input ข้อมูลที่เราต้องการ
ในฟอร์มแบบ two-way binding ผ่าน ngModel โดยจะต้องกำหนด name ให้กับ input ที่ต้องการเชื่อมก่อนใช้งาน
ngModel หรืออีกวิธีคือหากไม่กำหนด name ก็ให้กับหนด ngModelOptions ให้มีค่า standalone เป็น true ก็ได้
    ทบทวนบทความเกี่ยวกับการใช้งาน Template Driven Form ใน Angular ได้ที่
    
ตัวอย่างเช่นเรากำหนดการเชื่อมข้อมูลกับ input ที่ใช้เป็น username กรณีกำหนด name ก็จะเป็นดังนี้
 
<ion-item>		
  <ion-label floating>Username</ion-label>
  <ion-input type="text" [(ngModel)]="user.username" name="username"></ion-input>
</ion-item>
 
หรือกรณีไม่กำหนด name ก็กำหนด ngModelOptions เป็นแบบนี้ก็ได้
 
<ion-item>		
  <ion-label floating>Username</ion-label>
  <ion-input type="text" [(ngModel)]="user.username" [ngModelOptions]="{standalone: true}"></ion-input>
</ion-item>
 
อย่างไรก็ตามแนะนำเป็นแบบแรก จะสื่อได้เข้าใจมากกว่า
 
รูปแบบการใช้งาน ngModel ข้างต้น เราทำการเชื่อมโยงกับตัวแปร user ซึ่งเป็นตัวแปร object ที่เราต้องทำการสร้างไว้
ใน page component โดยสามารถใช้การกำหนด interface เพื่อจัดรูปแบบของข้อมูลได้ เราจะได้ไฟล์ login.ts ใหม่
เป็นดังนี้
 
ไฟล์ login.ts
 
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';

// กำหนดรูปแบบของชนิดข้อมูลผ่าน interface
interface UserLogin{
  username:string,
  password:string
}

@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {
  public user:UserLogin; // กำหนดตัวแปร

  constructor(public navCtrl: NavController, public navParams: NavParams) {
	// กำหนดค่าเริ่มต้นให้กับตัวแปร 
    this.user = {
      username:'',
      password:''
    }
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad LoginPage');
  }
  
  // ฟังก์ชั่นส่งค่าเมื่อ submit ฟอร์ม
  doLogin(){
    console.log(this.user);
  }  

}
 
จากโค้ด เราสร้างรูปแบบของข้อมูลผ่าน interface สร้างตัวแปร user และ กำหนดค่าเริ่มต้นให้กับตัวแปร
user ให้มีค่า usernmae และ password เริ่มต้นเป็นค่า ว่าง  และเรามีฟังก์ชั่นจำลองการส่งค่าเมื่อ submit
ฟอร์ม ชื่อ doLogin()   
    เมื่อเราได้ส่วนของการจัดการแล้ว ก็ให้ไปปรับส่วนของการแสดงผล โดยทำการเชื่อมโยงข้อมูลด้วย ngModel
ให้ครบทั้ง username และ password  รวมถึงกำหนด ngSubmit event ให้กับฟอร์มเพื่อไปทำคำสั่ง doLogin()
เมื่อกดที่ปุ่ม submit  เราก็จะได้ในส่วนของฟอร์มในไฟล์ login.html เป็นดังนี้
 
ไฟล์ login.html (บางส่วน)
 
  <form (ngSubmit)="doLogin()">
    <ion-list>
      <ion-item>
        <ion-label floating>Username</ion-label>
        <ion-input type="text" [(ngModel)]="user.username" name="username"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label floating>Password</ion-label>
        <ion-input type="password" [(ngModel)]="user.password" name="password"></ion-input>
      </ion-item>
    </ion-list>
    <div>
      <button type="submit" block ion-button color="danger">Login</button>
    </div>
  </form>
 
เมื่อมีการเชื่อมข้อมูลเรียบร้อยแล้ว ให้ทดสอบกรอกข้อมูล username และ password แล้วกดที่ปุ่ม Login โดยในขณะ
ที่เรากรอกข้อมูล username และ password ตัวแปร user ใน page component ก็จะมีการเปลี่ยนแปลงค่าไปตามข้อมูล
ที่เรากรอก แล้วเมื่อทำคำสั่ง doLogin() ก็จะแสดงข้อมูลนั้นผ่านตัวแปร user สมมติเช่น เรากรอก username เป็น demo
กรอก password เป็น test เราก็จะได้ตัวแปร user มีค่าเป็นดังนี้
 
{username: "demo", password: "test"}
 
เราสามารถอ้างอิงค่าจากตัวแปร user นี้ไปทำการตรวจสอบเงื่อนไขอื่นๆ เพิ่มเติม ก่อนทำการส่งข้อมูลไปยัง service api 
เพื่อใช้งาน หรืออาจจะประยุกต์กรณีตรวจสอบข้อมูลแล้ว    ขึ้นแจ้งว่า ให้ผู้ใช้กรอกข้อมูลให้ครบถ้วนกรณี username 
หรือ password เป็นค่าว่าง ก็ได้
 


 

ส่งข้อมูลจากฟอร์มผ่าน Templates

    การส่งค่าข้อมูลจากฟอร์มผ่าน Templates หรือเข้าใจง่ายๆ ก็คือการอ้างอิงจากข้อมูลในฟอร์มโดยตรง โดยจะมีรูปแบบ
คล้ายๆ กับการใช้งาน ngModel ซึ่งก็เป็นรูปแบบการใช้งาน Template Driven Form ใน angular เช่นกัน 
    ในการใช้งานรูปแบบนี้ จะมีการส่งค่าของฟอร์มเข้าไปใช้งาน ต่างจากการ ngModel ที่เป็นการใช้งานค่าจากตัวแปรใน
page component โดยตรง ข้อดี ก็จะสะดวกในการจัดการกับฟอร์มเพิ่มขึ้น โดยสามารถจัดการผ่านส่วนของ template
ได้โดยตรง ข้อเสีย ก็อาจจะทำให้ template ดูกรกตาขึ้นกว่าเดิมหน่อย เพราะเราต้องกำหนดค่าต่างๆ เพิ่มเติมเข้าไปใน
template เพื่อใช้งาน
    ทบทวนบทความเกี่ยวกับการใช้งาน Template Driven Form ใน Angular ได้ที่
    
เรามาดูไฟล์ template ส่วนของฟอร์ม ให้เราแก้ไขไฟล์ login.html เป็นดังนี้
 
ไฟล์ login.html (เฉพาะส่วนของฟอร์ม)
 
  <form #form="ngForm" (ngSubmit)="doLogin(form)" novalidate>
    <ion-list>
      <ion-item>
        <ion-label floating>Username</ion-label>
        <ion-input type="text" required [(ngModel)]="user.username" name="username"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label floating>Password</ion-label>
        <ion-input type="password" required [(ngModel)]="user.password" name="password"></ion-input>
      </ion-item>
    </ion-list>
    <div>
      <button type="submit" block ion-button color="danger">Login</button>
    </div>
  </form>
 
จะเห็นส่วนของฟอร์มเรามีการกำหนดตัวแปร template variable reference หรือการอ้างอิงตัวแปร template ชื่อว่า
form โดยกำหนดนำหน้าด้วย #form ให้มีค่าเท่ากับ ngForm จากนั้นเราส่งค่าตัวแปร form นี้เข้าไปในฟังก์ชั่น 
doLogin(form) เพื่อไปใช้งานเมื่อ submit    ตัวแปร form จะมี property ที่ใช้งานหลักๆ คือ form.value คือค่าของ
ข้อมูลที่กำหนดด้วย ngModel ในตัวอย่างก็จะเป็น username กับ password ซึ่งถ้าเรากรอก username เป็น demo
กรอก password เป็น test เราก็จะได้ค่า form.value มีค่าเป็นดังนี้
 
{username: "demo", password: "test"}
 
ส่วน property อีกค่าของ form ก็คือ form.valid จะมีค่าเป็น true หรือ false  เป็นลักษณะของการตรวจสอบข้อมูล
ที่มีการเชื่อมด้วย ngModel อย่างในโค้ด จะเห็นว่าเรากำหนด required attribute เข้าไปทั้งใน username และ password
นั่นหมายความว่า ต้องกรอกข้อมูลทั้งสองค่านี้ จึงจะทำให้ form.valid เป็น true
 
ตัวอย่างเมื่อเรากรอกเฉพาะ username แล้วกดปุ่ม Login โดยยังไม่ได้กรอก password ก็จะแสดงดังรูป
 
 


 
 
จากรูปข้างบน ส่วนของ password มีการ highlight  เป็นสีแดง แต่ปุ่ม Loign นั้นก็ทำงาน และฟอร์มก็ส่งตัวแปร form
เข้าไปในฟังก์ชั่น doLogin() ตามปกติ แต่ค่า form.value จะเป็น 
 
{username: "demo", password: ""}
 
และ form.valid จะเป็นค่า false  โดยเราสามารถใช้ค่าเหล่านี้ในการกำหนดเงื่อนไขการตรวจสอบก่อนส่งค่าไปยัง service api
เพื่อใช้งานต่อได้
 
ไฟล์ login.ts (ส่วนอื่นเหมือนเดิม แก้ไขแค่ส่วนของ doLogin() )
 
  doLogin(form:any){
	// ทดสอบดูค่าต่างๆ ที่ส่งมาจากฟอร์ม 
    console.log(form);
    console.log(form.value);
    console.log(form.valid);
  }
 
จะเห็นว่าเราไม่ได้มีการใช้งานค่าผ่านตัวแปร user โดยตรงเหมือนวิธีแรก แต่เราจะใช้งานค่าผ่านตัวแปร form ที่ถูก
ส่งเข้ามา โดยจะอยู่ในส่วนของค่า form.value 
 
เราสามารถใช้ form.valid กำหนดให้ปุ่ม ทำการ disabled หากยังกรอกข้อมูลที่จำเป็นไม่ครบถ้วน โดยกำหนดค่า
ในส่วนของปุ่ม submit เป็นดังนี้
 
<button type="submit" [disabled]="!form.valid" block ion-button color="danger">Login</button>
 
การกำหนดข้างต้น หมายความว่า ถ้า form.valid เป็น false คือกรอกข้อมูลไม่ครบถ้วน ตัวนิเสธ ! ก็จะทำให้ได้
เป็นค่าตรงกันข้าม ก็คือ เท่ากับ true ก็จะได้เป็น disabled เท่ากับ true คือไม่สามารถกดปุ่มเพื่อ submit ได้
ดูตัวอย่างประกอบตามรูปด้านล่าง รูปแรก กรอกเฉพาะ username ปุ่ม จะ disabled  รูปที่สอง กรอกข้อมูลครับ
ปุ่ม จะสามารถกด submit ได้ปกติ
 
 
    




 

ส่งข้อมูลจากฟอร์มผ่าน FormBuilder

    การส่งข้อมูลจากฟอร์มผ่าน FormBuilder เป็นรูปแบบเดียวกับการใช้งาน Reactive Form ใน angular เป็นลักษณะ
ของการจัดการค่าต่างๆ ของฟอร์มใน page component มากกว่าการกำหนดการใช้งานใน template เหมือนสองรูปแบบ
ข้างต้นที่ผ่านมา กล่าวคือ การกำหนดรูปแบบของข้อมูล การกำหนดรูปแบบการตรวจสอบข้อมูลจะทำในส่วนของ page 
component class ข้อดี คือสามารถจัดการแก้ไขค่าต่างๆ ผ่าน component ที่เดียว และรองรับการปรับแต่งด้านโปรแกรม
ได้มากขึ้น ข้อเสีย ก็คือต้องทำการ import FormBuilder เข้ามาใช้งาน และเราต้องทำความเข้าใจวิธีการกำหนดค่า
ต่างๆ เพิ่มเติม
    ทบทวนบทความเกี่ยวกับการใช้งาน Reactive Form ใน Angular ได้ที่
 
ก่อนอื่นให้เราปรับไฟล์ login.html ในส่วนของฟอร์มใหม่ เป็นดังนี้
 
ไฟล์ login.html (เฉพาะส่วนของฟอร์ม)
 
  <form [formGroup]="user" (ngSubmit)="doLogin()">
    <ion-list>
      <ion-item>
        <ion-label floating>Username</ion-label>
        <ion-input type="text" formControlName="username"></ion-input>
      </ion-item>

      <ion-item>
        <ion-label floating>Password</ion-label>
        <ion-input type="password" formControlName="password"></ion-input>
      </ion-item>
    </ion-list>
    <div>
      <button type="submit" [disabled]="!user.valid" block ion-button color="danger">Login</button>
    </div>
  </form>
 
จะเห็นว่าเรามีการใช้งาน FormGroup property เชื่อมกับตัวแปร user ซึ่งเป็นข้อมูลประเภท formGroup ที่เรากำหนด
ใน page component และส่วนของการ submit เราไม่ได้ส่งค่าใดๆ เข้าไป    ส่วนเพิ่มเติมที่เราต้องกำหนด เพื่อใช้งาน
กับ input element ต่างๆ ก็คือกำหนด formControlName เพื่อใช้อ้างอิง 
    สังเกตส่วนของการกำหนด disabled ในปุ่ม จะเห็นว่าเราเปลี่ยนมาใช้เป็น user.valid ซึ่ง user ก็เป็นข้อมูลประเภท
formGroup ซึ่งถ้าฟอร์มมีการกรอกข้อมูลตามค่าที่กำหนดครบถ้วนก็จะทำให้ user.valid เท่ากับ true ซึ่งก็จะเหมือนกับ
form.valid เท่ากับ true
 
ต่อไปส่วนของไฟล์ page component class ในไฟล์ login.ts ให้เราปรับโค้ดใหม่เป็นดังนี้
 
ไฟล์ login.ts
 
import { Component } from '@angular/core';
import { Validators, FormBuilder, FormGroup } from '@angular/forms';
import { NavController, NavParams } from 'ionic-angular';

@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {
  public user:FormGroup;

  constructor(
    public navCtrl: NavController, 
    public navParams: NavParams,
    public formBuilder: FormBuilder 
  ) {
    this.user = this.formBuilder.group({
      username: ['', Validators.required],
      password: ['',Validators.required]
    });
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad LoginPage');
  }

  doLogin(){
    console.log(this.user.value);
    console.log(this.user.valid);
  }

}
 
ในบรรทัดที่ 2 เราต้องทำการ import ส่วนที่จำเป็นการใช้งาน FormBuilder เข้ามาใช้งาน จะเห็นว่าตัวแปร user
ในบรรทัดที่ 10 เราไม่มีการใช้งาน interface เพื่อกำหนดรูปแบบของข้อมูลแล้ว เราให้ตัวแปร user นี้เป็นข้อมูลประเภท
FormGroup 
บรรทัดที่ 15 เราทำการ inject FormGroup เข้ามาใช้งาน จากนั้น กำหนดค่าเริ่มต้น และเงื่อนไขการตรวจสอบข้อมูล
ของ user ตามบรรทัดที่ 17-20 ซึ่งจะเห็นว่า เรากำหนดค่าเริ่มต้นให้กับ username และ password เป็นค่าว่าง
ให้ตรวจสอบว่า ทั้งสองค่านี้ จำเป็นต้องกรอก ผ่านการกำหนด Validators.required 
สามารถไปย้อนศึกษาเกี่ยวกับการใช้งาน การกำหนดค่าต่างๆ ใน Reactive Form ใน Angular ได้ตามลิ้งค์ด้านบน
    ส่วนของการใช้งานค่าจาก FormGroup เราก็จะอ้างอิงค่าผ่าาน this.user.value และ ตรวจสอบค่าผ่าน this.user.valid
คล้ายกับกรณี user เป็นตัวแปร form หนึ่งที่ถูกส่งเข้ามา
 
 
จากรูปแบบวิธีการใช้งานการส่งค่าฟอร์มแบบต่างๆ ข้างต้น เราสามารถเลือกรูปแบบที่เหมาะสมตามแต่กรณี หรือตามความ
เหมาะสม อย่างเช่น เราคงไม่ใช่รูปแบบ FormBuilder กับช่อนค้นหาข้อมูล แต่ใช่แบบกำหนดผ่าน ngModel เป็นต้น
 
เนื้อหาในตอนหน้าจะเป็นอะไร โปรดรอติดตาม
 


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



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









เนื้อหาที่เกี่ยวข้อง









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





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

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


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


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







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