จะเห็นว่า หน้าจอของ ofbiz ส่วนใหญ่ render โดยใช้ screen component
ลองดูตัวอย่าง definition ของ screen สักอัน
<screen name="NewInvoice">
<section>
<actions>
<set field="title" value="New Invoice"/>
<set field="titleProperty" value="PageTitleEditInvoice"/>
<entity-one entity-name="Invoice" value-name="invoice"/>
</actions>
<widgets>
<decorator-screen name="CommonInvoiceDecorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
<section>
<widgets>
<label style="head1" text="${uiLabelMap.AccountingCreateNewSalesInvoice}"></label>
<include-form name="NewSalesInvoice" location="component://accounting/webapp/accounting/invoice/InvoiceForms.xml"/>
<label style="head1" text="${uiLabelMap.AccountingCreateNewPurchaseInvoice}"/>
<include-form name="NewPurchaseInvoice" location="component://accounting/webapp/accounting/invoice/InvoiceForms.xml"/>
</widgets>
</section>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
ลองมาดูว่า feature ของ screen นั้นมีอะไรบ้าง
เริ่มที่ child element ของ screen ก่อน กำหนดไว้ว่าต้องเป็น <section> เท่านั้น
<screen>
<section>
...
</section>
</screen>
ภายใน section สามารถมี element ได้ 4 แบบ
<screen>
<section>
<condition>...</condition>
<actions>...</actions>
<widgets>...</widgets>
<fail-widgets>...</fail-widgets>
</section>
</screen>
ตัว condition ก็คือ expression ที่จะถูก evaluate เมื่อ screen เริ่มทำงาน
ถ้าได้ผลลัพท์เป็น true ก็จะ
ทำการเรียกใช้ actions และ render output โดยใช้ block widgets
แต่ถ้าได้ผลลัพท์เป็น false ก็จะ
render ด้วย block fail-widgets แทน
Note: ตัว condition, action, และ fail-widgets ถือว่าเป็น optional element
จะมีหรือไม่มีก็ได้
condition block ส่วนใหญ่จะไว้ใช้ check พวก authorize เช่น
<condition>
<or>
<if-has-permission permission="ORDERMGR" action="_VIEW"/>
</or>
</condition>
ส่วนภายใน action block, มีคำสั่งให้ใช้อีก 9 คำสั่ง
ซึ่งขอยกรายละเอียดไปพูดใน post หน้า
ภายใน widgets หรือ fail-widgets เราสามารถมี element ได้ดังนี้
- section
Note: จะเห็นว่าใน widgets ก็สามารถมี section ซ้อนอยู่ข้างในได้อีก - container
container ก็คือ wrapper ที่ไว้จัดกลุ่ม widget
การทำงานภายในของมัน ก็คือเวลามัน render html มันจะ render
<div> block คร่อม widget ที่อยู่ข้างในมัน - include-screen
อันนี้ตรงไปตรงมา ก็คือ include screen อื่นๆเข้ามา - decorator-screen, decorator-section-include
อันนี้ถือเป็นหัวใจของการใช้ screen
ถ้าเราสังเกตดูหน้าจอของ ofbiz เวลาใช้งาน
จะเห็นว่าเวลาเราเลือก action ต่างๆ หน้าจอส่วนใหญ่จะไม่เปลี่ยนแปลง
ส่วนที่เปลี่ยน จะเป็นแค่ region เล็กๆเท่านั้น
ofbiz ก็เลยนำ decorator pattern มาใช้สำหรับ render code ที่ซ้ำๆกัน
วิธีใช้ก็คือ<screen>
<section>
<widgets>
<decorator-screen name="CommonFixedAssetDecorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
... widget go here.
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
<screen name="CommonFixedAssetDecorator">
<section>
<widgets>
<decorator-screen name="main-decorator" location="${parameters.mainDecoratorLocation}">
<decorator-section name="body">
....
<decorator-section-include name="body"/>
</decorator-section>
</decorator-screen>
</widgets>
</section>
</screen>
Note: ใน ofbiz เรามักจะเห็น decorator ซ้อนไปซ้อนมาจนน่าปวดหัว - label
render string ธรรมดา
ซึ่งกรณีที่ render ออก html ก็จะมี ครอบให้ด้วย - include-form, include-menu, include-tree, content, sub-content, link, image, iterate-section
อันนี้เป็นเรื่องใหญ่อีกเรื่อง ที่จะยังไม่พูดถึง - platform-specific
อันนี้พบบ่อยมาก
วิธีใช้ก็ fix ตายตัว นั่นคือใช้เรียก html-template มาทำงาน
โดย support เฉพาะ Freemarker เท่านั้น<platform-specific>
<html>
<html-template location="component://accounting/webapp/accounting/invoice/sendPerEmail.ftl"/>
</html>
</platform-specific>
No comments:
Post a Comment