สร้าง App Windows8 ตามประสาคนทำเว็บ! [ตอนที่ 3/3]

image[69]

เอาละครับ จากตอนก่อนๆ เราได้รู้วิธีการ App ใหม่กันแบบเพียวๆ ตั้งแต่ต้นแล้ว แถมยังรู้วิธีดูดข้อมูลจากเว็บ Blognone กันแล้ว แต่เรายังไม่ได้หยอดข้อมูลลงไป คราวนี้เราต้องมาหยอดข้อมูลใส่หน้าจอกันแล้วละ

มันเป็นเรื่องของ Template

จากที่เราเคยมีข้อมูลแบบนี้อยู่ ซึ่งเป็น JSON หน้าตางามๆ แบบนี้ แล้วเราจะเอามันใส่หน้าจอได้ยังไงกันนะ?

image68

การทำแบบนี้ คือการใช้ Template ครับ Smile แน่นอนว่า ของ Microsoft เอง เขาก็มีวิธีทำ Template ในแบบของเขา ซึ่งมันจะหน้าตาเละเทะแบบนี้ เพราะว่ามันมีความสามารถสูงล้นฟ้ามาก (สามารถ Binding ข้อมูลเข้ากับ Attribute ใดๆ ก็ได้) คุณพระ! นี่มันภาษา HTML แน่เหรอครับ!

image

แต่ของเรา จะเป็นแบบนี้ วิ้งๆ

image

มาเจอกับ Handlebars

image

คุณ Handlebars จะเป็นผู้ช่วยของเราในวันนี้ครับ มาดูว่าแกจะช่วยเราได้ยังไง ขั้นแรก ก็ต้องไปเชิญแกมาจาก NuGet ก่อน แล้วเอามาวางต่อจาก jQuery

image

ใช้ตัวธรรมดานะ (runtime เป็นของ Template แบบ Pre-compiled)

image

จากนั้น เราก็ต้องสร้าง Template กันก่อน โดย Template เราจะสร้างไว้ใน Tag Script ซึ่ง Windows 8 จะไม่เข้ามายุ่ง เพราะเราตั้ง Content-Type เป็น text/html

image

สังเกตว่า เราอยากได้อะไรไว้ตรงไหน ก็แค่ใส่ {{{สิ่งที่ต้องการ}}} เท่านั้นเอง ส่วนที่ {{image}} มีแค่ 2 อัน เพราะว่าถ้าแบบ 2 อัน มันจะแปลง HTML ให้เป็น text แต่ว่าเราต้องการ title แบบ HTML เลยต้องใช้ {{{title}} ครับ

แล้วการใช้งานละ ง่ายมาาากกก เราไปเพิ่มโค๊ดในฟังก์ชั่น readData ที่เราสร้างไว้ในตอนที่ 2 ครับ

image

อธิบายโค๊ด

  1. ผมไปแก้ฟังก์ชั่น ReadBlognoneHome ให้ Return ตัว Array มาด้วย (ตอนที่ 2 จะไม่ได้ Return อะไร)
  2. การใช้งาน Template จะต้อง Compile มันก่อน แล้วเก็บเอาไว้ใช้ เราจะได้ฟังก์ชั่นออกมา
  3. และท้ายสุด เราทำการเรียกฟังก์ชั่น featuredTemplate แล้วส่ง element แรกของ result ไปให้ (มันคือ featured ในหน้า blognone) แล้วทำการแปลงมันเป็น jQuery Object โดยการเอา $(…) ครอบไป แล้วก็สั่ง appendTo div ที่เราเตรียมไว้

สำหรับหน้า HTML ตอนนี้มีแค่นี้เอง

image

Loop ใน Template

ยากขึ้นมาหน่อย สำหรับ Layout ของผม ใช้ Div แบ่งคอลัมน์เป็น แถวๆ โดยแถวแรก มีการแสดง header เพื่อเป็นตัวแบ่งด้วย ตัวเทมเพลทก็เลยต้องมี Loop อยู่ข้างใน สังเกตว่า ใช้ {{#each ชื่อ}} ครับ

image

ทีนี้ เนื่องจากว่า ผมต้องการให้แต่ละคอลัมน์ มีแค่ 3 ข่าว จึงต้องหาตัวช่วยเล็กน้อย ซึ่งจริงๆ เราจะเขียน For-Loop แล้วใช้ฟังก์ชั่น slice ของ Array ก็ได้ แต่อ่านแล้วมันเข้าใจยาก ผมเลยไปหาฟังก์ชั่น Iterator ซึ่งจะแบ่งค่าออกมา (Tokenization) ทีละ 3 ตัวให้เราครับ ไปได้มาจาก http://jsfiddle.net/fkling/k6GGC/ แต่แก้ไขเพิ่มเติมเล็กน้อยให้มัน Return false ถ้าจบ Array แล้ว (ของเดิมจะวนไปที่จุดเริ่มต้นใหม่อีกรอบ)

image

และโค๊ดสำหรับหยอดข้อมูลใส่ลงไป ก็มีดังนี้ครับ สังเกตว่า ในช่วงที่ 1 ผมตั้งค่า header เอาไว้ แล้วตอนหลังไปตั้งให้มันเป็น false เพราะว่าใน Template เราสามารถใส่ {#{if}} ได้ ถ้าเจอ header เป็น false มันก็จะเลิกแสดง ส่วนเพื่อให้เราสามารถส่งข้อมูลไปให้ Template ได้หลายค่า เราก็สร้างเป็น JSON เหมือนเดิมในกล่องที่ 2

image

ผลงาน

หลังจากรันแล้ว ก็จะได้ผลดังนี้

image

แต่ว่า…ถ้าเป็นจอใหญ่ละ…

image

นั่นก็เพราะว่า เราไปกำหนดตายตัวไว้ว่า แต่ละคอลัมน์จะต้องมี 3 อันเท่านั้นยังไงละ แล้วจะยังไงดีละทีนี้? ก็ต้องไปแก้ไขโค๊ดเสียหน่อย เพื่อให้แสดงผลให้เต็มหน้าจอ (แต่จะว่าไปมันก็ไม่ค่อยสวยนะ Sad smile)

image

image

ภาพบน จอ 27” 2560x1440

image

ภาพบน จอ 23” 1920x1080

หมายเหตุ: ผมได้ลองใช้ column-count ดูแล้ว ซึ่งควรจะทำให้ article นั้นแสดงผลเรียงบนลงล่าง แล้วค่อยขึ้นซ้ายไปขวา แต่ผลออกมาไม่เป็นที่น่าพอใจอย่างมาก แล้วบางครั้งทำให้ Simulator Crash อีกต่างหาก เลยใช้วิธีบ้านๆ แบบนี้ไปก่อน Smile (ลอง Flexbox ก็หาทางให้มันเรียงจากบนลงล่าง แล้วค่อยซ้ายไปขวาไม่ได้อีกเหมือนกัน)

พอก่อนดีกว่า

พอมาลองคิดๆ ดูยังมีอีกหลายเรื่องเลยที่อยากจะเขียนต่อ แต่ผมเชื่อว่า ทั้งสามตอนนี้ น่าจะช่วยให้คุณที่เป็นคนทำเว็บ เขียน JavaScript เป็นนิดหน่อย พอจะสร้าง App ง่ายๆ ที่ไปดูดหน้าเว็บชาวบ้านเขามาแสดงผลได้แล้ว ต่อจากนี้ ก็แล้วแต่ฝีมือ JavaScript ของคุณแล้วละ ว่าจะlnw ขิงๆ ขนาดไหน แล้วถ้ามีโอกาส ผมจะมาเขียนต่อ ในอีกหลายๆ ประเด็นครับ Smile