>> เข้าประเด็นกันเลย
- ผมไม่ต้องการคลาส EndAnimatorWidget เพราะคลาส EndAnimator ไม่จำเป็นต้องมีหน้าตาใดๆ
- ผมไม่ต้องการอินเตอร์เฟส EndAnimatorClientRpc เพราะไม่มีงานของหน้าบ้านที่ต้องคุยกับหลังบ้านด้วย rpc ของหน้าบ้าน (ขอโทษครับเรื่องศัพท์แปลกๆของผม)
- ผมไม่ต้องการคลาส EndAnimatorState เพราะจะไม่มีการรับส่งค่าใดๆผ่านตัวแปร
- ผมต้องการ ให้คลาส EndAnimator ลงทะเบียนอินเตอร์เฟส EndAnimatorServerRpc เพื่อคอยรับสัญญาณจากคลาส EndAnimatorConnector แค่นั้น
- ผมต้องการ ให้อินเตอร์เฟส EndAnimatorServerRpc ใช้ rpc คอยรับการทำงานจาก EndAnimatorConnector เมื่อจาวาสคริปต์ทำงาน 'animationend' ของ animation ใดๆ
- ผมต้องการ ให้คลาส EndAnimatorConnector มีบริการลงทะเบียน 'animationend' สำหรับ component ใดๆที่ต้องการให้เล่น animation
- และเมื่อ 'animationend' ปรากฏ นั่นหมายความว่า EndAnimatorServerRpc จะต้องทำงานและส่งการทำงานนี้ให้กับอินเตอร์เฟสที่ทำหน้าที่เสมือนรับฟังเหตุการณ์เล่น animation เสร็จสิ้น
- ผมขอตั้งชื่ออินเตอร์เฟสที่ทำหน้าที่เสมือนรับฟังเหตุการณ์เล่น animation เสร็จสิ้นนี้ว่า AnimationEndListener ซึ่งมีบริการ onAnimationEnd สำหรับทุก component ที่เรียกใช้คลาส EndAnimator ครับ
>> ดังนั้นคลาส EndAnimator หรือก็คือหัวใจของเรื่องนี้จึงต้องมี AnimationEndListener บังคับให้ใช้อยู่ภายใน, สำหรับทุก component ที่มันรับฟัง (listen) การเล่น animation จนเสร็จสิ้นจะถูกบังคับทำ onAnimationEnd จาก EndAnimatorServerRpc อีกทอดหนึ่ง รายละเอียดทั้งหมดดังรูป
- เพื่อที่จะให้คลาสนี้ส่ง component ใดๆไปให้คลาส EndAnimatorConnector จึงต้องให้สืบทอด com.vaadin.server.AbstractExtension, เช่นเดียวกับคลาส EndAnimatorConnector ที่ต้องเป็นลูกของ com.vaadin.client.extensions.AbstractExtensionConnector มิเช่นนั้นมันจะคุยกันไม่รู้เรื่อง
>> คลาส EndAnimatorConnector เมื่อเป็นลูกของ com.vaadin.client.extensions.AbstractExtensionConnector จึงถูก override เมธอด extend เพื่อที่จะนำ component ที่รับมาจากคลาส EndAnimator มาเพิ่มการฟัง 'animationend' (ชื่อมาตราฐาน) ด้วยการเรียก registerCssCallback ที่ทำงาน native javascript code จับเหตุการณ์การเล่น animation เสร็จสิ้นของแต่ละ browser, เมื่อ callback function ถูกเรียกก็จะส่งผลให้ onAnimationEnd ของอินเตอร์เฟส AnimationEndEventHandler ทำงาน มันจะส่งสัญญาณไปบอกต่อ EndAnimatorServerRpc ซึ่งจะกลับไปที่คลาส EndAnimator เพื่อทำงาน onAnimationEnd ของอินเตอร์เฟส AnimationEndListener นั่นเอง
>> ทีนี้มาดูกันว่าใช้งานอย่างไร และเหตุใดผมจึงต้องหาวิธีการอย่างนี้มาจัดการกับเหตุการณ์ end animation
- ปรับปรุงคลาส MyUI ให้สร้างสี่เหลี่ยมขนาด 300 x 300 px ออกมา ให้ชื่อมันว่า animateLayout
- ใส่ style sheet พื้นหลังสีเหลือง ให้เล่น animation ของไลบรารีตัวนี้ http://daneden.github.io/animate.css/ มันก็จะหมุนติ้วๆ
- และเมื่อ animation เล่นจบลง ผมก็ให้เปลี่ยนพื้นหลังเป็นสีเขียว (อย่างที่เพื่อนๆชาว css ทราบกันดีอยู่แล้วว่าจะเกิดการ override สีพื้นหลัง) พร้อมกับลบ animation หมุนติ้วๆนี้ออก
- เพื่อนๆจะเห็นว่า css class names ที่ถูกเพิ่มเข้าไปเมื่อไม่ลบออกก็จะฝังอยู่ในแท็ก html (ได้แก่ .background-yellow และ .background-green) ซึ่งงานของผมไม่ต้องการให้ css class names ของ animation ฝังอยู่จึงสั่งให้ลบออกไปหลังจาก animation เล่นจบลง ทีนี้เวลาผมกดปุ่ม F5 หรือเคลื่อนย้าย dom ก็จะไม่เกิดการเล่น animation เหล่านี้อีก เป็นว่าบรรลุเป้าหมายครับผม (ยิ้ม)
>> และนี่คือโครงสร้างทั้งหมดของโปรเจ็กต์และการ include css animation ดังข้างต้นเข้าไป
*** ผมสังเกตว่า
- หากแก้ไข (รวมถึง เพิ่มไฟล์ ลบไฟล์) widgetset ก็ต้อง compile มันใหม่ ผมจะคลิกขวาที่โปรเจ็กต์แล้วเลือกคำสั่ง Build
- หากแก้ไข vaadin หลังบ้าน (ในที่นี้ได้แก่คลาส EndAnimator และ MyUI) ให้คลิกขวาที่โปรเจ็กต์แล้วเลือกคำสั่ง Run ได้เลย (มันจะ compile กับ deploy ให้อัตโนมัติ)
>> ใครที่สนใจ gwt อยากลองมาเขียน vaadin ผมขอบอกว่ามันแจ่มมาก! เป็น open source เพื่อทำงานกับ JEE เหมือนกันแต่ compile ไวกว่า ลองไปเยี่ยมชมพวกเขาสิครับ
https://vaadin.com/home
คืนนี้ฝันดีจ้า
ไม่มีความคิดเห็น:
แสดงความคิดเห็น