<f: metadata> อะไร, <f: viewParam> และ <f: viewAction> ใช้สำหรับอะไรได้บ้าง


149

ทุกคนสามารถชี้แจงได้อย่างไรว่าเราสามารถใช้งานทั่วไปหรือตัวอย่างในโลกแห่งความเป็นจริงตัวอย่างข้อมูลนี้ได้หรือไม่

<f:metadata>
    <f:viewParam id="id" value="#{bean.id}" />
    <f:viewAction action="#{bean.init}" />
</f:metadata>

คำตอบ:


288

ประมวลผลพารามิเตอร์ GET

<f:viewParam>จัดการการตั้งค่าการแปลงและการตรวจสอบของ GET พารามิเตอร์ มันเหมือน<h:inputText>แต่สำหรับพารามิเตอร์ GET

ตัวอย่างต่อไปนี้

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>

ทำโดยทั่วไปดังต่อไปนี้:

  • idได้รับค่าพารามิเตอร์คำขอตามชื่อ
  • แปลงและตรวจสอบหากจำเป็น (คุณสามารถใช้required, validatorและconverterคุณลักษณะและรัง<f:converter>และ<f:validator>ในนั้นเช่นเดียวกับ<h:inputText>)
  • หากการแปลงและการตรวจสอบสำเร็จแล้วให้ตั้งค่าเป็นคุณสมบัติ bean ที่แสดงโดย#{bean.id}ค่าหรือหากไม่มีvalueแอตทริบิวต์ให้ตั้งค่าเป็นชื่อผู้ร้องขอidเพื่อให้สามารถใช้งานได้#{id}ในมุมมอง

ดังนั้นเมื่อคุณเปิดหน้าfoo.xhtml?id=10ดังนั้นค่าพารามิเตอร์10จะถูกตั้งค่าใน bean ด้วยวิธีนี้ก่อนที่จะแสดงผลมุมมอง

สำหรับการตรวจสอบความถูกต้องตัวอย่างต่อไปนี้ตั้งค่าพารามิเตอร์เป็นrequired="true"และอนุญาตเฉพาะค่าระหว่าง 10 และ 20 ความล้มเหลวในการตรวจสอบความถูกต้องใด ๆ จะส่งผลให้มีข้อความปรากฏขึ้น

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
</f:metadata>
<h:message for="id" />

การดำเนินการทางธุรกิจกับพารามิเตอร์ GET

คุณสามารถใช้<f:viewAction>สำหรับสิ่งนี้

<f:metadata>
    <f:viewParam id="id" name="id" value="#{bean.id}" required="true">
        <f:validateLongRange minimum="10" maximum="20" />
    </f:viewParam>
    <f:viewAction action="#{bean.onload}" />
</f:metadata>
<h:message for="id" />

กับ

public void onload() {
    // ...
}

<f:viewAction>อย่างไรก็ตามใหม่ตั้งแต่ JSF 2.2 (คน<f:viewParam>มีอยู่แล้วตั้งแต่ JSF 2.0) หากคุณไม่สามารถอัปเกรดได้แสดงว่าทางออกที่ดีที่สุดของคุณคือใช้<f:event>แทน

<f:event type="preRenderView" listener="#{bean.onload}" />

อย่างไรก็ตามสิ่งนี้ถูกเรียกใช้ในทุกคำขอ คุณต้องตรวจสอบอย่างชัดเจนว่าคำขอไม่ใช่ postback หรือไม่:

public void onload() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // ...
    }
}

เมื่อคุณต้องการข้ามกรณี "การแปลง / การตรวจสอบความถูกต้องล้มเหลว" เช่นกันให้ทำดังนี้:

public void onload() {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    if (!facesContext.isPostback() && !facesContext.isValidationFailed()) {
        // ...
    }
}

การใช้<f:event>วิธีนี้เป็นวิธีแก้ปัญหา / แฮ็คนั่นคือเหตุผลที่<f:viewAction>แนะนำใน JSF 2.2


ผ่านพารามิเตอร์มุมมองไปยังมุมมองถัดไป

คุณสามารถ "pass-through" พารามิเตอร์มุมมองในลิงค์การนำทางโดยการตั้งค่าincludeViewParamsคุณลักษณะtrueหรือโดยการเพิ่มincludeViewParams=trueพารามิเตอร์คำขอ

<h:link outcome="next" includeViewParams="true">
<!-- Or -->
<h:link outcome="next?includeViewParams=true">

ซึ่งสร้างด้วย<f:metadata>ตัวอย่างข้างต้นโดยทั่วไปลิงค์ต่อไปนี้

<a href="next.xhtml?id=10">

ด้วยค่าพารามิเตอร์ดั้งเดิม

วิธีการนี้จะต้องใช้ที่next.xhtmlมียัง<f:viewParam>พารามิเตอร์เดียวกันมากมิฉะนั้นจะไม่ได้รับการส่งผ่าน


ใช้แบบฟอร์ม GET ใน JSF

<f:viewParam>นอกจากนี้ยังสามารถใช้ร่วมกับ "ธรรมดา HTML" ฟอร์ม GET

<f:metadata>
    <f:viewParam id="query" name="query" value="#{bean.query}" />
    <f:viewAction action="#{bean.search}" />
</f:metadata>
...
<form>
    <label for="query">Query</label>
    <input type="text" name="query" value="#{empty bean.query ? param.query : bean.query}" />
    <input type="submit" value="Search" />
    <h:message for="query" />
</form>
...
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
     ...
</h:dataTable>

ด้วยพื้น@RequestScopedถั่วนี้:

private String query;
private List<Result> results;

public void search() {
    results = service.search(query);
}

โปรดทราบว่า<h:message>สำหรับ<f:viewParam>HTML ไม่ใช่แบบธรรมดา<input type="text">! นอกจากนี้โปรดทราบว่าค่าอินพุตจะแสดง#{param.query}เมื่อ#{bean.query}ว่างเปล่าเนื่องจากค่าที่ส่งจะไม่ปรากฏขึ้นเลยเมื่อมีข้อผิดพลาดในการตรวจสอบหรือการแปลง โปรดทราบว่าโครงสร้างนี้ไม่ถูกต้องสำหรับองค์ประกอบการป้อนข้อมูล JSF (กำลังทำ "ภายใต้ครอบคลุม" แล้ว)


ดูสิ่งนี้ด้วย:


@BalusC สิ่งที่ควรเป็นขอบเขตของ "bean" เมื่อใช้ร่วมกับ faces-redirect = true มันจะทำงานได้ตามที่คาดหวังหรือไม่หากตั้งค่าขอบเขตเป็น "@RequestScoped"
Geek

@Geek: การเปลี่ยนเส้นทางสร้างคำขอ GET ใหม่ ขอบเขต bean ของต้นทางและเป้าหมาย bean ไม่เกี่ยวข้อง อย่างไรก็ตามคุณควรคำนึงถึงความเป็นไปได้ของการร้องขอ GET ใหม่เพื่อพิจารณาคำขอและดูขอบเขตที่กำหนด ดูstackoverflow.com/questions/7031885/…
BalusC

@BalusC สิ่งที่คุณหมายถึงโดย "คุณควรคำนึงถึงความเป็นไปได้ของการร้องขอ GET ใหม่เข้าบัญชีคำขอและดูถั่วขอบเขต"
Geek

@Geek: พวกเขาจะถูกทิ้งและสร้างใหม่เพราะขอบเขตของพวกเขาจะสิ้นสุดและเริ่มต้น
BalusC

@BalusC คำตอบที่ครอบคลุม "เมื่อคุณต้องการใช้คุณลักษณะ '@' PostConstruct เช่นเดียวกับการดูถั่วที่กำหนดขอบเขตซึ่งไม่ได้เรียกใช้กับทุกคำขอตรวจสอบว่าคำขอไม่ใช่ postback หรือไม่" หากคำขอนั้นไม่ได้ถูกเรียกใช้ในทุกคำขอแล้วทำไมต้องตรวจสอบว่าคำขอดังกล่าวเป็น postback หรือไม่
Uluk Biy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.