jsf-2 - JSF2 में किसी क्रिया से नेविगेट करते समय आप व्यू पैरामीटर कैसे पास करते हैं?




(6)

एक बीन के संदर्भ के बिना एक समाधान:

<h:button value="login" 
        outcome="content/configuration.xhtml?i=1" />

मेरी परियोजना में मुझे इस दृष्टिकोण की आवश्यकता थी:

<h:commandButton value="login" 
        action="content/configuration.xhtml?faces-redirect=true&amp;i=1"  />

मेरे बीन में एक क्रिया से, मैं दृश्य पैरामीटर की अपेक्षा रखने वाले दूसरे पृष्ठ पर रीडायरेक्ट करने का प्रयास कर रहा हूं। JSF2 में ऐसा करने का अनुशंसित तरीका क्या है?

उदाहरण के लिए, मेरा स्रोत पृष्ठ कहें: http://localhost/page1.xhtml

इसमें एक कमांड बटन है जो एक क्रिया को कॉल करता है:

<h:commandButton value="submit" action="#{myBean.submit}" />

जहां मेरा बीन दिखता है:

@ManagedBean
@RequestScoped
public class MyBean {

private int id;

public String submit() {
    //Does stuff
    id = setID();
    return "success";
}

और अब, मैं http://localhost/page2.xhtml?id=2 पर नेविगेट करने के लिए 'सबमिट' कार्रवाई की वापसी चाहता हूं

मैंने अपने नेविगेशन मामले में व्यू-पैरा के साथ ऐसा करने की कोशिश की है, लेकिन अजीब परिणामों के साथ। चेहरे-कॉन्फ़िगर स्निपेट निम्न की तरह दिखता है:

<navigation-rule>
    <from-view-id>/page1.xhtml</from-view-id>
    <navigation-case>
        <from-outcome>success</from-outcome>
        <to-view-id>/page2.xhtml</to-view-id>
        <redirect>
            <view-param>
                <name>id</name>
                <value>#{myBean.id}</value>
            </view-param>
        </redirect>
    </navigation-case>
</navigation-rule>

अजीब व्यवहार, भले ही MyBean स्कोप्ड का अनुरोध करने के लिए सेट है, यह केवल myBean.getId () को कॉल करता है, पहली बार जब मैं अपना एप्लिकेशन लोड करता हूं, और सभी बाद के कॉल के लिए उसी मान का पुन: उपयोग करता हूं, पृष्ठ 2 के लिए गलत दृश्य पैरामीटर का उत्पादन करता है।

इसलिए मैं ऐसा करने का एक बेहतर तरीका ढूंढ रहा हूं, या एक कारण / समाधान है कि प्रत्येक बार मेरे बीन से व्यू-पैरा का अनुरोध क्यों नहीं किया जा रहा है।


आप इसे प्राइमफेस का उपयोग करके कर सकते हैं:

<p:button 
      outcome="/page2.xhtml?faces-redirect=true&amp;id=#{myBean.id}">
</p:button>

नीचे टैग को रीडायरेक्ट करने के लिए बस देखा गया विशेषता जोड़ें:

<redirect include-view-params="true">
    <view-param>
        <name>id</name>
        <value>#{myBean.id}</value>
    </view-param>
</redirect>

Here कुछ नेविगेशन उदाहरण दिए गए हैं।


एक अच्छे समाधान के बिना, जो मैंने काम में पाया वह बीन रिटर्न में बस मेरी क्वेरी स्ट्रिंग का निर्माण कर रहा है:

public String submit() {
    // Do something
    return "/page2.xhtml?faces-redirect=true&id=" + id;
}

समाधानों का सबसे लचीला नहीं है, लेकिन ऐसा लगता है कि मैं इसे कैसे करना चाहता हूं।

क्वेरी स्ट्रिंग बनाने की प्रक्रिया को साफ करने के लिए इस दृष्टिकोण का भी उपयोग करना: http://www.warski.org/blog/?p=185


जेएसएफ में पैरामीटर पास करने के बारे में अनजान बात यह है कि आप यह तय नहीं करते कि क्या (कार्रवाई में) भेजना है, बल्कि आप जो प्राप्त करना चाहते हैं (लक्ष्य पृष्ठ में)।

जब आप एक कार्यवाही करते हैं जो एक रीडायरेक्ट के साथ समाप्त होता है, तो लक्ष्य पृष्ठ मेटाडेटा लोड होता है और सभी आवश्यक पैरामीटर पढ़ा जाता है और यूआरएल को पैराम के रूप में जोड़ा जाता है।

ध्यान दें कि यह बिल्कुल वही तंत्र है जैसा किसी भी अन्य जेएसएफ बाध्यकारी के साथ है: आप इनपुटटेक्स्ट के मूल्य को एक स्थान से नहीं पढ़ सकते हैं और इसे कहीं और लिख सकते हैं। व्यू पैराम में परिभाषित मूल्य अभिव्यक्ति का उपयोग पढ़ने (रीडायरेक्ट से पहले) और लिखने के लिए (रीडायरेक्ट के बाद) दोनों के लिए किया जाता है।

अपने बीन के साथ आप बस करते हैं:

@ManagedBean
@RequestScoped
public class MyBean {

private int id;

public String submit() {
    //Does stuff
    id = setID();
    return "success?faces-redirect=true&includeViewParams=true";
}

// setter and getter for id

अगर प्राप्त करने वाले पक्ष में है:

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

यह वही करेगा जो आप चाहते हैं।


आप Mojarra 2.0 / 2.1 / 2.2 बग को ठीक करने के लिए निम्न स्क्रिप्ट का उपयोग कर सकते हैं (नोट: यह MyFaces में प्रकट नहीं होता है)। यह स्क्रिप्ट javax.faces.ViewState फ़ॉर्म के लिए छुपा फ़ील्ड javax.faces.ViewState जो AJAX अद्यतन के बाद कोई भी दृश्य स्थिति पुनर्प्राप्त नहीं की गई।

jsf.ajax.addOnEvent(function(data) {
    if (data.status == "success") {
        fixViewState(data.responseXML);
    }
});

function fixViewState(responseXML) {
    var viewState = getViewState(responseXML);

    if (viewState) {
        for (var i = 0; i < document.forms.length; i++) {
            var form = document.forms[i];

            if (form.method == "post") {
                if (!hasViewState(form)) {
                    createViewState(form, viewState);
                }
            }
            else { // PrimeFaces also adds them to GET forms!
                removeViewState(form);
            }
        }
    }
}

function getViewState(responseXML) {
    var updates = responseXML.getElementsByTagName("update");

    for (var i = 0; i < updates.length; i++) {
        var update = updates[i];

        if (update.getAttribute("id").match(/^([\w]+:)?javax\.faces\.ViewState(:[0-9]+)?$/)) {
            return update.textContent || update.innerText;
        }
    }

    return null;
}

function hasViewState(form) {
    for (var i = 0; i < form.elements.length; i++) {
        if (form.elements[i].name == "javax.faces.ViewState") {
            return true;
        }
    }

    return false;
}

function createViewState(form, viewState) {
    var hidden;

    try {
        hidden = document.createElement("<input name='javax.faces.ViewState'>"); // IE6-8.
    } catch(e) {
        hidden = document.createElement("input");
        hidden.setAttribute("name", "javax.faces.ViewState");
    }

    hidden.setAttribute("type", "hidden");
    hidden.setAttribute("value", viewState);
    hidden.setAttribute("autocomplete", "off");
    form.appendChild(hidden);
}

function removeViewState(form) {
    for (var i = 0; i < form.elements.length; i++) {
        var element = form.elements[i];
        if (element.name == "javax.faces.ViewState") {
            element.parentNode.removeChild(element);
        }
    }
}

इसे त्रुटि पृष्ठ के <h:body> के अंदर बस <h:outputScript name="some.js" target="head"> के रूप में शामिल करें। यदि आप इस बात की गारंटी नहीं दे सकते कि प्रश्न में पृष्ठ जेएसएफ <f:ajax> का उपयोग करता है, जो jsf.js स्वत: समावेशन को ट्रिगर करेगा, तो आप अतिरिक्त जोड़ना चाहेंगे if (typeof jsf !== 'undefined') चेक jsf.ajax.addOnEvent() कॉल से पहले, या स्पष्ट रूप से इसे शामिल करने के लिए

<h:outputScript library="javax.faces" name="jsf.js" target="head" />

ध्यान दें कि jsf.ajax.addOnEvent केवल मानक जेएसएफ <f:ajax> को कवर करता है और उदाहरण के लिए प्राइमफ़ेस <p:ajax> या <p:commandXxx> जैसा कि वे नौकरी के लिए jQuery कवर के अंतर्गत उपयोग करते हैं। प्राइमफेसेस AJAX अनुरोधों को कवर करने के लिए, निम्न जोड़ें:

$(document).ajaxComplete(function(event, xhr, options) {
    if (typeof xhr.responseXML != 'undefined') { // It's undefined when plain $.ajax(), $.get(), etc is used instead of PrimeFaces ajax.
        fixViewState(xhr.responseXML);
    }
}

अपडेट करें यदि आप जेएसएफ यूटिलिटी लाइब्रेरी ओमनीफेसेस का उपयोग कर रहे हैं, तो यह जानना अच्छा है कि उपरोक्त 1.7 ओमनीफेस का हिस्सा बन गया है। यह निम्नलिखित स्क्रिप्ट को <h:body> में घोषित करने का विषय है। showcase भी देखें।

<h:body>
    <h:outputScript library="omnifaces" name="fixviewstate.js" target="head" />
    ...
</h:body>






jsf jsf-2