มาลองสร้าง dictionary ไว้ใช้เอง ด้วย ionicframework นี้
เราจะใช้งาน dict longdo เขามี api อย่างง่ายให้แล้ว แต่คงต้อง
เอามาปรับให้เข้ากับ angularjs อีกนิดหน่อย
อธิบายหลักการทำงาน พอเข้าใจกันก่อน
เราจะมีหน้า app สำหรับพิมพ์คำค้นหา โดยกำหนดว่า
จะเริ่มค้นหาคำที่พิมพ์เมื่อ มีความยาวคำตั้งแต่ 2 คำขึ้นไป
โดยส่งค่าคำค้นไปเรียกไฟล์ ที่เราทำการไปดึงค่าจาก longdo dict
แล้วแปลงเป็น json object อีกที
สิ่งที่จะได้รู้เพิ่มเติม เกี่ยวกับการใช้งาน angularjs directive และ service เพิ่มเติม
ได้แก่ (บางรายการมีในเนื้อหา การใช้งาน angularjs ดูเพิ่มในหมวด angularjs ได้)
ng-keyup เมื่อกดป่ม แล้วปล่อย สำหรับแป้นพิมพ์
ng-keydown เมื่อกดปุ่ม ขณะกดยังไม่ปล่อย สำหรับแป้นพิมพ์
ng-click เมื่อคลิก ถ้ามือถือก็คือ เมื่อ กดที่ รายการใดๆ
ng-show ซ่อนหรือแสดงเนื้อหาหรือข้อมูลหรือส่วนที่กำหนด
ng-bind-html แปลงค่าข้อมูลที่ได้รับแสดงเป็นแบบ html
service ได้แก่
$http สำหรับส่งค่าเพื่อเรียกใช้ข้อมูล คล้าย ajax
$timeout สำหรับตั้งเวลา คล้าย setTImeout ใน javascript
โครงสร้างไฟล์
index.html ไฟล์หลัก
app.js ไฟล์ javascript
get_dict.php ไฟล์ php สำหรับเรียกใช้และแปลงข้อมูลเป็น json object
tpl\mydict.html ไฟล์ template ในโฟลเดอร์ tpl แสดงหน้าฟอร์มค้นหา
1. โค้ดไฟล์ index.html
ไฟล์นี้จะเป็นไฟล์ธรรมดา เราจะใช้งาน navigation โดยใช้ ion-nav-view
เนื้อหาเกี่ยวกับส่วนนี้ มีในบทความก่อนหน้าไม่ขอกล่าวถึง
<!DOCTYPE html> <html ng-app="myDictionary"> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <meta name="msapplication-tap-highlight" content="no" /> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <link href="css/ionic.css" rel="stylesheet"> <script type="text/javascript" src="js/ionic.bundle.min.js"></script> <script type="text/javascript" src="app.js"></script> <style type="text/css"> table,table tr td{border: 1px solid #E2E2E2;padding:5px;} </style> <title>My Dictionary</title> </head> <body ng-controller="myIonicHome"> <ion-nav-bar class="bar bar-header bar-balanced"> </ion-nav-bar> <ion-nav-view animation="slide-in-up"> </ion-nav-view> </body> </html>
สังเกตว่าจะมีการใส่ css style เข้ามาใน header
<style type="text/css"> table,table tr td{border: 1px solid #E2E2E2;padding:5px;} </style>
ที่ต้องเพิ่มเข้ามา เนื่องจาก ค่าที่ได้รับจาก การค้นหาด้วย longdo dict จะมี
การใช้งานตาราง การกำหนดตรงนี้ เพื่อให้มีผลกับการแสดง ตารางให้สวยงามเท่านั้น
2. ไฟล์ mydict.html
ไฟล์ template นี้จะถูกเรียกใช้งานทันที ที่เราเปิด app เข้ามา เนื่องจากเรามีการ
กำหนดการใช้งาน ion-nav-view และมีการตั้งค่าใน app.js
<ion-view title="Dictionary"> <div class="bar bar-subheader item-input-inset"> <label class="item-input-wrapper"> <i class="icon ion-ios7-search placeholder-icon"></i> <input type="search" ng-model="keyword" ng-keydown="setkeyword()" ng-keyup="showMydict(keyword,event=$event)" placeholder="Search"> </label> <button ng-click="keyword='';dict_result='พิมพ์คำศัพท์ที่ต้องการค้นหา';showloading=false;" class="button button-clear"> Cancel </button> </div> <ion-content class="scroll-content ionic-scroll has-subheader"> <div class="list card"> <button ng-show="showloading" class="button button-icon button-block"> <i class="icon ion-loading-c"></i> Loading... </button> <div ng-show="!showloading" class="item item-text-wrap" ng-bind-html="dict_result"> </div> </div> </ion-content> </ion-view>
สังเกต บรรทัดที่ 2 กับ 11
ปกติ เราจะมีแค่ header ด้านบน แต่กรณีนี้ เราจะมี subheader
css class ชื่อ bar-subheader หมายถึง ส่วนที่แสดงถัดต่อลงมาจาก header
ดังนั้นความสัมพันธ์ กับ บรรทัดที่ 11 ส่วนของ เนื้อหา จะต้องขยับลงมาอีก
จึงมีการใช้งาน css class ชื่อ has-subheader ให้เนื้อหาขยับลงมาให้เพมาะสม
มาดูส่วนของช่องค้นหา
<label class="item-input-wrapper"> <i class="icon ion-ios7-search placeholder-icon"></i> <input type="search" ng-model="keyword" ng-keydown="setkeyword()" ng-keyup="showMydict(keyword,event=$event)" placeholder="Search"> </label>
ng-model="keyword"
มีการเก็บค่าของช่องค้นหาไว้ในตัวแปร keyword ด้วย ng-model
ng-keyup="showMydict(keyword,event=$event)"
เรียกใช้งานฟังก์ชั่น showMydict() เมื่อมีการกรอกข้อมูล กรณีกดแป้นพิมพ์ และปล่อย
แล้ว โดยทำการส่งค่า keyword เข้าไปในฟังก์ชั่น พร้อมกับ ตัวแปร event ของแป้นพิมพ์
โดยตัวแปร event ของแป้นพิมพ์นี้ เราจะเอาไปเช็คการกดปุ่ม บางปุ่ม โดยใช้งาน
event.keyCode เป็นเงื่อนไขว่า ถ้ากดปุ่มที่มีรหัสนี้ ทำงานหรือไม่ เป็นต้น
ปุ่ม cancel
<button ng-click="keyword='';dict_result='พิมพ์คำศัพท์ที่ต้องการค้นหา';showloading=false;" class="button button-clear"> Cancel </button>
อันนี้ไม่มีอะไร มีการใช้การ ng-click เมื่อกดแล้ว ให้ไปกำหนดค่า เช่น
keyword='' ให้ค่า keyword เป็นค่าว่าง
dict_result='พิมพ์คำศัพท์ที่ต้องการค้นหา' ให้ค่าในส่วนเนื้อหา ผลลัพธ์เป็นข้อความเริ่มต้น
showloading=false ให้ค่าสำหรับการแสดง ข้อควม loading เป็น false คือ ไม่แสดง
ข้อความ loading
<button ng-show="showloading" class="button button-icon button-block"> <i class="icon ion-loading-c"></i> Loading... </button>
ในที่นี้จะใช้ปุ่ม เป็นข้อความ loading มีการกำหนดการแสดง ตามตัวแปร showloading
ขึ้นกับว่า ถ้าเป็น true ก็จะแสดง ถ้าเป็น false ก็ไม่แสดง
ng-show="showloading"
ส่วนสุดท้ายในไฟล์ template
ส่วนแสดงเนื้อหา และรายละเอียดผลลัพธ์ทีได้
<div ng-show="!showloading" class="item item-text-wrap" ng-bind-html="dict_result"> </div>
มีการกำหนดให้แสดง ด้วย ng-show แต่ให้ใช้ค่า เป็นตรงข้าม กับตัว loading
!showloading คือ ถ้าตัว loading แสดง เนื้อหาจะไม่แสดง เป็นต้น
ส่วนของการแสดงผลลัพธ์นี้ มีการใช้งาน ng-bind-html ใช้สำหรับแสดง
เนือหาที่ได้ในรุปแบบ html
ng-bind-html="dict_result" แสดงค่าจากตัวแปร dict_result ในรูปแบบ html
3. ไฟล์ app.js
คำอธิบายแสดงในโค้ด
angular.module("myDictionary", ["ionic"]) // สร้าง module .config(function ($stateProvider, $urlRouterProvider) { // ตั้งค่า $urlRouterProvider $stateProvider .state('intro', { // กำหนด ชื่อ state url: '/', // เข้ามาหนักแรก templateUrl: 'tpl/mydict.html', // ให้แรียกใช้ ไฟล์ template mydict.html controller: 'welcomeCtrl' // กำหนด ชื่อ controller }) $urlRouterProvider.otherwise("/"); // กรณีอื่นๆ ให้ไปที่ url เท่ากับ / }) // กำหนดการใช้งานใน welcomeCtrl controller เรียกใช้ $http และ $timeout .controller("welcomeCtrl",function($scope,$http,$timeout){ var timeoutID=null; // ค่า id สำรหับกำหนด timeout ใน angularjs เรียกว่า promise $scope.dict_result="พิมพ์คำศัพท์ที่ต้องการค้นหา"; //กำหนดค่าเริ่มต้นของผลลัพธ์ $scope.showloading=false; // ค่าเริ่มต้นการแสดงของ loading // ฟังก์ชั่น แสดงข้อมูลการแปล รับค่า keyword และ event ของ แป้นพิมพ์เข้ามาด้วย $scope.showMydict = function(keyword,event){ // ถ้าความยาวของข้อความมากกว่า 2 และ ไม่การกดปุ่มลบ if(keyword.length>2 && event.keyCode!=8){ // 8 เป้น keycode ของปุ่มลบ backspace timeoutID=$timeout(function(){ // กำหนดการทำงานแบบหน่วงเวลา $scope.showloading=true; // เมื่อเริ่มทำงานให้แสดงปุ่ม loading $scope.dict_result=""; // ให้ค่าผลลัพธ์ เป็นค่าว่าง // ใช้ service $http เรียกข้อมูล แบบ jsonp ส่งค่า keyword และ callback ไป $http.jsonp("http://localhost/ninenikc/demo/ionic/get_dict.php?callback=JSON_CALLBACK&keyword="+keyword).success(function(result){ // พอสำเร็จ ได้ผลลัพธ์ นำมาไว้ในตัวแปร ผลลัพธ์ เพื่อไปแสดง $scope.dict_result=result[0].data_result; // เนื่องจากข้อมูลเป็นชุดเดียว จึงใช้ key เท่ากับ 0 $scope.showloading=false; // ซ่อนปุ่ม loading }); },2000); // เริ่มทำงานน 2 วินาที // 1000 เท่ากับ 1 วินาที } }; // ฟังก์ชั่น ยกเลิกการหน่วงเวลาเพื่อเริ่มต้นนับใหม่ // ที่ต้องมีส่วนนี้เพื่อ ต้องการให้ป้อนคำให้เสร็จก่อน ค่อยทำงาน $scope.setkeyword = function(){ $timeout.cancel(timeoutID); // คำสั่งยกเลิกการหน่วงเวลา เพื่อเริ่มนับค่าใหม่ }; }) .controller("myIonicHome",function($scope){ });
4. ไฟล์ get_dict.php
ไฟล์ นี้ใช้สำหรับสร้าง json string แล้วส่งค่าไปใช้งาน
โดยจะทำการไปดึงข้อมูลการแปลจาก longdo dict มาแล้วมาจัดเก็บ
ในรูปแบบ array แล้วแปลงเป็น json string อีกที
<?php header("Content-type:application/json; charset=UTF-8"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); // ตรวจสอบว่ามีการส่งคำค้นมาหรือไม่ if(isset($_GET['keyword']) && trim($_GET['keyword'])!=""){ $keyword=trim($_GET['keyword']); // นำผลลัพธ์การค้นหา จาก longdo dictionary มาไว้ในตัวแปร $data=file_get_contents("http://dict.longdo.com/mobile.php?search=".$keyword); // $data_result=strip_tags($data,"<table><td><tr><font><style><br>"); // แสดงส่วนของเนื้อหาที่จำเป็นต้องแสดง }else{ // กรณีไม่มีการส่งคำค้นมา $data_result="โปรดระบุคำที่ต้องการแปล"; // แสดงข้อความแจ้งเตือน } $json_data[]=array( "keyword"=>trim($_GET['keyword']), "data_result"=>$data_result ); $json= json_encode($json_data); if(isset($_GET['callback']) && $_GET['callback']!=""){ echo $_GET['callback']."(".$json.");"; }else{ echo $json; } exit; ?>
มาดูตัวอย่าง การทำงานของ dictionary ฝีมือเราดู สามารถใช้ phonegap แปลงเป็น
ไฟล์ สำหรับมือถือ ไว้ใช้งานได้