문제

When viewing this page with ?mode=test, the button doesn't work. It loads this page without ?mode=test, but h:panelGroup is rendered (because mode is set somewhere else). I use two methods of sending mode (h:inputHidden f:param) and to the server and nothing helps. View scoped bean is not available in CDI. What is the possible solution to this?

XHTML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <f:view>
        <f:metadata>
            <f:viewParam name="mode" value="#{test.mode}" />
        </f:metadata>
        <h:panelGroup layout="block" rendered="#{test.mode.equals('test')}">
            <h:form>
                <h:inputHidden value="#{test.mode}" />
                <h:commandButton value="Run a method" action="#{test.method}">
                    <f:param name="mode" value="#{test.mode}" />
                </h:commandButton>
            </h:form>
        </h:panelGroup>
        <h:messages />
    </f:view>
</html>

Java

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named("test")
@RequestScoped
public class TestBean {
    private String mode;

    public void method() {
        System.out.print(mode);
    }

    public String getMode() {
        return mode;
    }

    public void setMode(String mode) {
        this.mode = mode;
    }
}
도움이 되었습니까?

해결책

You've got a wide range of possibilities. The easiest one for you is not to bind the view parameter to the backing bean, just keep it bound to the view:

test.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
    <f:metadata>
        <f:viewParam name="mode" value="#{mode}" />
    </f:metadata>
    <h:form rendered="#{mode eq 'test'}">
        <h:commandButton value="Run a method" action="#{test.method(mode)}" />
    </h:form>
    <h:messages />
</f:view>
</html>

Test.java

@Named
@RequestScoped
public class Test {

    public void method(String mode) {
        System.out.print(mode);
    }

}

If you however would like to switch to @ViewScoped, CDI compatible annotation is now available in JSF 2.2 version. The namespaces you're using suggest you do use that version, so go with it. For JSF prior versions, there's also the chance to do it with custom Omnifaces' annotation.

See also:

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top