สำหรับเนื้อหานี้จะเป็นตอนที่สอง ต่อจากตอนที่แล้ว ที่เราวางโครงสร้างรูปแบบ
คร่าวๆ ของ app ว่าจะเป็นในลักษณะไหน
แนวทางใช้งาน ionic material สร้างระบบสมาชิก ร่วมกับ SQLite
https://www.ninenik.com/content.php?arti_id=734 via @ninenik
โดยในตอนที่สอง จะเป็นการประยุกต์ให้สามารถใช้งานได้จริง ตั้งแต่การสมัคร
สมาชิก แล้วบันทึกลงฐานข้อมูล จากนั้นลิ้งค์ไปหน้าโพรไฟล์ ดึงข้อมูลจากฐาน
ข้อมูลมาแสดงในหน้าโพรไฟล์ และเมื่อล็อกเอาท์ออกจากระบบ ก็จะแสดงหน้า
ล็อกอิน ให้ผู้ใช้ทำการกรอก username และ password ใหม่อีกครั้งถ้าต้องการ
ล็อกอิน ประมาณนี้เป็นต้น
ก่อนอื่น เราต้องตรวจสอบ cordova plugin ที่จำเป็นเพิ่มเติมก่อน ซึ่งจะได้แก่
1 2 3 4 5 6 7 8 | SQLite - สำหรับใช้งาน db cordova-sqlite-storage 1.4.8 "Cordova sqlite storage plugin" Toast - สำหรับแสดงสถานะการทำงาน cordova-plugin-x-toast 2.5.2 "Toast" Dialogs - สำหรับขึ้นข้อความแจ้งเตือน หรือแจ้งการทำงานcordova-plugin-dialogs cordova-plugin-dialogs 1.2.1 "Notification" SpinnerDialog - สำหรับขึ้นแสดง loading พร้อมข้อความ (เคยติดตั้งแล้วในบทความ map) cordova-plugin-spinner-dialog 1.3.1 "SpinnerDialog" |
1. ตรวจสอบ plugin ด้วยคำสั่ง
1 | C:\phonegap\learn001>phonegap plugin ls |
หากยังไม่ได้ติดตั้ง plugin ข้างต้น ให้ทำการติดตั้งด้วยคำสั่ง ดังนี้
ติดตั้ง plugin SQLite ด้วยคำสั่ง
1 | C:\phonegap\learn001>cordova plugin add cordova-sqlite-storage |
ติดตั้ง plugin Toast ด้วยคำสั่ง
1 | C:\phonegap\learn001>cordova plugin add cordova-plugin-x-toast |
ติดตั้ง plugin Dialogs ด้วยคำสั่ง
1 | C:\phonegap\learn001>cordova plugin add cordova-plugin-dialogs |
ติดตั้ง plugin SpinnerDialog ด้วยคำสั่ง
1 | C:\phonegap\learn001>cordova plugin add cordova-plugin-spinner-dialog |
2. กำหนดในส่วนของ controller ของหน้าล็อกอิน หน้าสมัครสมาชิก และหน้าโพรไฟล์
ในส่วนของ controller ให้เปิดไฟล์ controllers.js ในโฟลเดอร์ js ขึ้นมา
แล้วปรับโค้ดให้เป็นดังนี้ (คำอธิบายแสดงในโค้ด หากมีอธิบายเพิ่มเติมจะแสดงด้านล่างโค้ด)
AppCtrl ส่วนของ controller หลัก
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | .controller( 'AppCtrl' , function ($scope, $ionicModal, $ionicPopover, $timeout, $ionicPopup) { $scope.loginData = {}; $scope.isExpanded = false ; $scope.hasHeaderFabLeft = false ; $scope.hasHeaderFabRight = false ; var navIcons = document.getElementsByClassName( 'ion-navicon' ); for ( var i = 0; i < navIcons.length; i++) { navIcons.addEventListener( 'click' , function () { this .classList.toggle( 'active' ); }); } //////////////////////////////////////// // Layout Methods //////////////////////////////////////// $scope.hideNavBar = function () { document.getElementsByTagName( 'ion-nav-bar' )[0].style.display = 'none' ; }; $scope.showNavBar = function () { document.getElementsByTagName( 'ion-nav-bar' )[0].style.display = 'block' ; }; $scope.noHeader = function () { var content = document.getElementsByTagName( 'ion-content' ); for ( var i = 0; i < content.length; i++) { if (content[i].classList.contains( 'has-header' )) { content[i].classList.toggle( 'has-header' ); } } }; $scope.setExpanded = function (bool) { $scope.isExpanded = bool; }; $scope.setHeaderFab = function (location) { var hasHeaderFabLeft = false ; var hasHeaderFabRight = false ; switch (location) { case 'left' : hasHeaderFabLeft = true ; break ; case 'right' : hasHeaderFabRight = true ; break ; } $scope.hasHeaderFabLeft = hasHeaderFabLeft; $scope.hasHeaderFabRight = hasHeaderFabRight; }; $scope.hasHeader = function () { var content = document.getElementsByTagName( 'ion-content' ); for ( var i = 0; i < content.length; i++) { if (!content[i].classList.contains( 'has-header' )) { content[i].classList.toggle( 'has-header' ); } } }; $scope.hideHeader = function () { $scope.hideNavBar(); $scope.noHeader(); }; $scope.showHeader = function () { $scope.showNavBar(); $scope.hasHeader(); }; $scope.clearFabs = function () { var fabs = document.getElementsByClassName( 'button-fab' ); if (fabs.length && fabs.length > 1) { fabs[0].remove(); } }; $scope.noShadow = function () { var headerBar = document.getElementsByTagName( 'ion-header-bar' ); for ( var i = 0; i < headerBar.length; i++) { if (!headerBar[i].classList.contains( 'no-shadow' )) { headerBar[i].classList.add( 'no-shadow' ); } } }; $scope.hasShadow = function () { var headerBar = document.getElementsByTagName( 'ion-header-bar' ); for ( var i = 0; i < headerBar.length; i++) { if (headerBar[i].classList.contains( 'no-shadow' )) { headerBar[i].classList.remove( 'no-shadow' ); } } }; // ตัวแปรสำหรับกำหนด การซ่อนหรือแสดงเมนูสมาชิก false คือซ่อนเมนูสมาชิก $scope.showMemberMenu = false ; // สร้างฟังก์ชั่น สำหรับเรียกใช้ เพื่อกำหนดการ กำหนดค่าตัวแปรเพื่อซ่อนหรือแสดงเมนู $scope.setMemberMenu = function (status){ $scope.showMemberMenu = status; }; // กำหนดตัวแปรไว้สำหรับเก็บ id ของสมาชิกที่สมัครในเครื่องนั้นๆ $scope.sesMemberID = null ; // สร้างฟังก์ชั่นสำหรับกำหนดค่า id ให้สามารถเรียกใช้งานจาก $scope หลักได้ $scope.setMemberID = function (memID){ $scope.sesMemberID = memID; }; // สร้างฟังก์ชั่นสำหรับเรียกดูค่า id ของสมาชิกจาก $scope หลักได้ $scope.getMemberID = function (){ return $scope.sesMemberID; }; }) |
สังเกตว่าเรามีการเพิ่ม ตัวแปร sesMemberID เข้ามาเพื่อใช้เก็บค่า member_id ของสมาชิก
รวมทั้งมีการสร้างฟังก์ชั่นกำหนดค่า และฟังก์ชั่นเรียกใช้งานค่า member_id เพื่อไว้สำหรับเรียกใช้
จาก controller ย่อยอื่นๆ ได้
LoginCtrl ส่วนของ controller หน้า login
การทำงานของหน้านี้คือ เริ่มกำหนดค่าว่างในตัวแปรที่ใช้ในฟอร์มล็อกอิน ตรวจสอบข้อมูลที่กรอก
ในฟอร์มล็อกอินว่ากรอกข้อมูลครบหรือไม่ จากนั้นส่งค่าข้อมูลไปตรวจสอบกับ db ว่ามีข้อมูล
ของสมาชิกนั้นหรือไม่ หากมีข้อมูลก็ให้เข้าสู่ระบบ และไปยังหน้าโพรไฟล์
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | .controller( 'LoginCtrl' , function ($scope, $timeout, $stateParams, ionicMaterialInk ,$ionicPlatform, $cordovaDialogs, $cordovaToast, $state) { $scope.$parent.clearFabs(); $scope.$parent.hasShadow(); $timeout( function () { $scope.$parent.hideHeader(); }, 0); // กำนหดค่าเริ่มต้นของฟอร์มหน้าสมัครสมาชิก ให้เป็นค่าว่าง $scope.login = { input_user: '' , input_pass: '' }; // เรียกใช้ฟังก์ชั่นจาก AppCtrl หลัก เพื่อซ่อนเมนูสมาชิก โดยส่งค่า false เข้าไป $scope.$parent.setMemberMenu( false ); // สร้างฟังก์ชั่นสำหรับเรียกใช้ Toast plugin $scope.showToast = function (str, duration, position){ $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin return $cordovaToast .show(str, duration, position) .then( function (success) { // success }, function (error) { // error }); }); }; var db = null ; $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin // ตรวจสอบและทำการเชื่อมต่อกับ db db = window.sqlitePlugin.openDatabase({ name: 'my.db' , location: 'default' }, function (db) { $scope.showToast( 'Open DB Success' , 'long' , 'bottom' ); }, function (error) { $scope.showToast( 'Open database ERROR: ' + JSON.stringify(error), 'long' , 'bottom' ); }); }); // สร้างฟังก์ชั่นสำหรับล็อกอิน รับค่า data จาก object login $scope.loginMember = function (data){ $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin // ตรวจสอบถ้ากรอกข้อมูลไม่ครบ if (data.input_user== "" || data.input_pass== "" ){ $cordovaDialogs.alert( 'โปรดกรอกข้อมูลให้ครบถ้วน' , 'ข้อมูลจำเป็น' , 'ตกลง' ) .then( function () { return false ; }); return false ; } // แสดงข้อมูลที่ส่งเข้ามา เวลาใช้จริงสามารถลบออกได้ $scope.showToast( ' user: ' + data.input_user + ' pass: ' + data.input_pass + '' , 'long' , 'bottom' ); // เริ่มทำงานของคำสั่ง db db.transaction( function (tx) { // กำหนดคำสั่ง sql ค่าที่รับมาตรวจสอบ แทนด้วย ? // คำสั่งนี้คือเช็คว่า มีสมาชิกที่ user และ pass ตรงหรือไม่ ตัวเล็กตัวใหญ่มีค่าต่างกัน var query = "SELECT member_id, member_user, member_phone" + " FROM member WHERE member_user = ? AND member_pass = ? " ; // ทำคำสั่ง sql ส่งค่าเข้าไปให้ตรงกับจำนวน ในที่นี้มี data.input_user และ data.input_pass tx.executeSql(query, [data.input_user, data.input_pass], function (tx, resultSet) { // ถ้าพบรายการใน db if (resultSet.rows.length){ // นำค่า ID ของสมาชิกไปเก็บในตัวแปร sesMemberID ด้วยฟังก์ชั่น setMemberID // ที่อยู่ใน controller หลัก $scope.$parent.setMemberID(resultSet.rows.item(0).member_id); // ขึ้นแจ้ง เข้าสู่ระบบสำเร็จ และเปลี่ยนไปหน้า profile ด้วย $stat.go() $cordovaDialogs.alert( 'เข้าสู่ระบบสำเร็จ' , 'เข้าสู่ระบบ' , 'ตกลง' ) .then( function () { $state.go( 'app.profile' ); }); } else { // ไม่พบข้อมูล ขึ้นแจ้งเตือนว่ามีข้อผิดพลาด $cordovaDialogs.alert( 'ชื่อหรือรหัสผ่านไม่ถูกต้อง' , 'เกิดข้อผิดพลาด' , 'ตกลง' ) .then( function () { return false ; }); return false ; } }, function (tx, error) { // ข้อความแจ้ง SELECT error $scope.showToast( 'SELECT error: ' + error.message, 'long' , 'bottom' ); }); }, function (error) { $scope.showToast( 'transaction error: ' + error.message, 'long' , 'bottom' ); }, function () { $scope.showToast( 'transaction ok' , 'long' , 'bottom' ); }); }); }; ionicMaterialInk.displayEffect(); }) |
สังเกตว่าใน LoginCtrl มีการเรียกใช้งาน $ionicPlatform, $cordovaDialogs, $cordovaToast, $state เพิ่มเข้ามา โดย
$ionicPlatform สำหรับตรวจสอบความพร้อมของอุปกรณ์ก่อนเรียกใช้ plugin
$cordovaDialogs สำหรับ alert แจ้งเตือนข้อความ
$cordovaToast สำหรับข้อความแจ้งสถานะ
$state สำหรับเชื่อมโยงหรือลิ้งค์ไปหน้าต่างๆ
RegistCtrl ส่วนของ controller หน้า register
การทำงานหน้านี้คือ เริ่มกำหนดตัวแปรค่าว่างให้กับข้อมูลในฟอร์มสมัครสมาชิก
ทำการตรวจสอบการกรอกข้อมูลในฟอร์มก่อนส่งข้อมูล ทำการส่งข้อมูลไปบันทึกใน db
จากนั้นลิ้งค์ไปยังหน้าโพรไฟล์
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | .controller( 'RegistCtrl' , function ($scope, $timeout, $stateParams, ionicMaterialInk ,$ionicPlatform, $cordovaDialogs, $cordovaToast, $state) { $scope.$parent.clearFabs(); $scope.$parent.hasShadow(); $timeout( function () { $scope.$parent.hideHeader(); }, 0); // กำนหดค่าเริ่มต้นของฟอร์มหน้าสมัครสมาชิก ให้เป็นค่าว่าง $scope.reg = { input_user: '' , input_pass: '' , input_phone: '' }; // เรียกใช้ฟังก์ชั่นจาก AppCtrl หลัก เพื่อซ่อนเมนูสมาชิก โดยส่งค่า false เข้าไป $scope.$parent.setMemberMenu( false ); // สร้างฟังก์ชั่นสำหรับเรียกใช้ Toast plugin $scope.showToast = function (str, duration, position){ $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin return $cordovaToast .show(str, duration, position) .then( function (success) { // success }, function (error) { // error }); }); }; var db = null ; $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin // ตรวจสอบและทำการเชื่อมต่อกับ db db = window.sqlitePlugin.openDatabase({ name: 'my.db' , location: 'default' }, function (db) { // เชื่อมต่อ db สำเร็จ $scope.showToast( 'Open DB Success' , 'long' , 'bottom' ); // เริ่มทำงานของคำสั่ง db db.transaction( function (tx) { // เวลามีการทดสอบและเพิ่มฟิลด์หรือแก้ไขตารางควรเปิดคอมเม้นการลบตารางก่อน // นั้นหมายถึงตารางจะถูกสร้างและจัดรูปแบบใหม่ทุกครั้ง ข้อมูลตารางจะรีเซ็ต ล้างค่า // พอว่างโครงสร้างตารางเรียบร้อยแล้ว ให้ปิดคอมเม้นไว้เหมือนเดิม เพื่อให้ข้อมูลยังคงอยู่ // tx.executeSql('DROP TABLE IF EXISTS member'); // ทำคำสั่งสร้างตาราง member ถ้ายังไม่มี tx.executeSql( '' + 'CREATE TABLE IF NOT EXISTS member ' + '(member_id integer primary key,' + 'member_user text, ' + 'member_pass text,' + 'member_phone text)' + '' ); }, function (error) { $scope.showToast( 'transaction error: ' + error.message, 'long' , 'bottom' ); }, function () { $scope.showToast( 'transaction ok' , 'long' , 'bottom' ); }); }, function (error) { $scope.showToast( 'Open database ERROR: ' + JSON.stringify(error), 'long' , 'bottom' ); }); }); // สร้างฟังก์ชั่นสำหรับสมัครสมาชิก รับค่า data จาก object reg $scope.registerMember = function (data){ $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin // ตรวจสอบให้กรอกข้อมูลให้ครบถ้วน if (data.input_user== "" || data.input_pass== "" || data.input_phone== "" ){ $cordovaDialogs.alert( 'โปรดกรอกข้อมูลให้ครบถ้วน' , 'ข้อมูลจำเป็น' , 'ตกลง' ) .then( function () { return false ; }); return false ; } // แสดงข้อมูลที่ส่งเข้ามา เวลาใช้จริงสามารถลบออกได้ $scope.showToast( ' user: ' + data.input_user + ' pass: ' + data.input_pass + ' phone: ' + data.input_phone + '' , 'long' , 'bottom' ); // เริ่มทำงานของคำสั่ง db db.transaction( function (tx) { // จัดรูปแบบคำสั่ง sql สำหรับบันทึกข้อมูล ค่าที่รับมาบันทึกจะแทนด้วย ? // ในที่นี้จะส่งมาแค่ 3 ค่า ส่วน member_id นั้นเป็น PRIMARY KEY เป็น auto incremet // โดยอัตโนมัติ var query = "INSERT INTO member" + " (member_user, member_pass, member_phone) " + " VALUES (?,?,?)" ; // ทำงานคำสั่ง sql tx.executeSql(query, [data.input_user, data.input_pass, data.input_phone], function (tx, res) { // เมื่อทำการบันทึกข้อมูลสำเร็จ // ใช้ค่า member_id จาก res.insertId แล้วกำหนดค่าด้วยฟังก์ชั่น setMemberID() $scope.$parent.setMemberID(res.insertId); $scope.showToast( 'insertId: ' + res.insertId + ' -- probably 1' , 'long' , 'bottom' ); $scope.showToast( 'rowsAffected: ' + res.rowsAffected + ' -- should be 1' , 'long' , 'bottom' ); // แจ้งการสมัครสมาชิกสำเร็จ และให้ไปที่หน้า profile $cordovaDialogs.alert( 'ทำการสัมครสมัครสมาชิกเรียบร้อยแล้ว' , 'สมัครสมาชิกใหม่' , 'ตกลง' ) .then( function () { $state.go( 'app.profile' ); }); }, function (tx, error) { $scope.showToast( 'INSERT error: ' + error.message, 'long' , 'bottom' ); }); }, function (error) { $scope.showToast( 'transaction error: ' + error.message, 'long' , 'bottom' ); }, function () { $scope.showToast( 'transaction ok' , 'long' , 'bottom' ); }); }); }; ionicMaterialInk.displayEffect(); }) |
ProfileCtrl ส่วนของ controller หน้า profile
การทำงานของหน้านี้ทำการเชื่อมกับ db แล้วไปดึงข้อมูลของสมาชิกที่ทำการล็อกอิน
สำหรับ หรือสมาชิกที่สมัครสมาชิกมาแสดง โดยอิงการดึงค่าจาก member_id ที่มีการเก็บ
ค่าไว้ใน $scope ที่อยู่ใน controller หลัก เมื่อพบข้อมูลก็นำมากำหนดในตัวแปร แล้วเรียกใช้
งานในหน้าโพรไฟล์อีกที
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | .controller( 'ProfileCtrl' , function ( $scope, $stateParams, $timeout, ionicMaterialMotion, ionicMaterialInk, $ionicPlatform, $cordovaSpinnerDialog, $cordovaToast) { $scope.$parent.showHeader(); $scope.$parent.clearFabs(); $scope.isExpanded = false ; $scope.$parent.setExpanded( false ); $scope.$parent.setHeaderFab( false ); $scope.$parent.hasShadow(); // กำหนดตัวแปรสำหรับค่าเริ่มต้นของข้อมูลหน้าโพรไลฟ์ $scope.member_user = '' ; $scope.member_phone = '' ; // กำหนดให้แสดงเมนูสมาชิก $scope.$parent.setMemberMenu( true ); // สร้างฟังก์ชั่นสำหรับเรียกใช้ Toast plugin $scope.showToast = function (str, duration, position){ $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin return $cordovaToast .show(str, duration, position) .then( function (success) { // success }, function (error) { // error }); }); }; var db = null ; $ionicPlatform.ready( function () { // เตรียมก่อนเรียกใช้ plugin // ตรวจสอบและทำการเชื่อมต่อกับ db db = window.sqlitePlugin.openDatabase({ name: 'my.db' , location: 'default' }, function (db) { // เชื่อมต่อ db สำเร็จ $scope.showToast( 'Open DB Success' , 'long' , 'bottom' ); // แสดง spin dialog plugin จะใช้หรือไม่ก็ได้ นำมาใช้เผื่อใครไปประยุกต์เพิ่ม $cordovaSpinnerDialog.show( null , "รอสักครู่..กำลังโหลดข้อมูล" ); // แสดง loading $timeout( function () { // ซ่อนอัตโนมัติใน 300 มิลลิวินาที $cordovaSpinnerDialog.hide(); }, 300); // เริ่มทำงานของคำสั่ง db db.transaction( function (tx) { // เตรียมคำสั่ง sql ดึงข้อมูลสมาชิกอิงจาก member_id ที่เราเก็บไว้ใน $scope หลัก var query = "SELECT member_user, member_phone" + " FROM member WHERE member_id = ?" ; // ดึงค่า member_id จาก $scope หลักด้วยฟังก์ชั่น getMemberID() var id_member = $scope.$parent.getMemberID(); // ทำคำสั่ง sql ดึงข้อมูลตาม member_id tx.executeSql(query, [id_member], function (tx, resultSet) { // ถ้าพบข้อมูล if (resultSet.rows.length){ // นำข้อมูลที่ได้ มาไว้ในตัวแปร member_user และ member_phone // เพื่อแสดงในหน้า profile $scope.member_user = resultSet.rows.item(0).member_user; $scope.member_phone = resultSet.rows.item(0).member_phone; } $cordovaSpinnerDialog.hide(); }, function (tx, error) { $scope.showToast( 'SELECT error: ' + error.message, 'long' , 'bottom' ); }); }, function (error) { $scope.showToast( 'transaction error: ' + error.message, 'long' , 'bottom' ); }, function () { $scope.showToast( 'transaction ok' , 'long' , 'bottom' ); }); }, function (error) { $scope.showToast( 'Open database ERROR: ' + JSON.stringify(error), 'long' , 'bottom' ); }); }); $timeout( function () { ionicMaterialMotion.slideUp({ selector: '.slide-up' }); }, 300); $timeout( function () { ionicMaterialMotion.fadeSlideInRight({ startVelocity: 3000 }); }, 700); ionicMaterialInk.displayEffect(); }) |
3. ทำการ build apk ไฟล์แล้วนำไปทดสอบติดตั้งบนมือถือ
ด้วยคำสั่ง
1 | C:\phonegap\learn001>phonegap build android |
ให้ทำการทดสอบติดตั้งในมือถือ android ของเรา จะได้หน้าตา app ประมาณนี้
ในตัวอย่างมีส่วนของแผนที่ด้วย หากต้องการเห็นผลแผนที่ด้วย
อาจจะต้อง รีสตาร์ทเครื่องหนึ่งครั้ง







