为什么来自 f:viewParam 的数据在点击按钮之前就消失了

Why the data from f:viewParam dissapears before click on the button

我正在 JSF 上开发一个简单的 CRUD,我有一个重定向的视图,所以我应该在另一个视图中完成表单并更新元素,但是由于某种原因,视图参数的数据在单击更新按钮之前就消失了。

这是我的代码:

StateList.xhtml

...     
                <p:column headerText="Accion">

                    <p:button icon="pi pi-pencil"
                                     value="Editar"
                                     styleClass="edit-button rounded-button success-button"
                                     process="@this"
                                     outcome="StateEdit"
                    >
                        <f:param name="id" value="#{stateItem.id}"/>
                    </p:button>

...

状态编辑

    <ui:define name="metadata">
        <f:metadata>
            <f:viewParam name="id" value="#{stateController.recivedId}"/>

        </f:metadata>
    </ui:define>

    <ui:define name="title">Editar estado</ui:define>

    <ui:define name="viewname">
        <li>Inicio</li>
        <li><i class="fa fa-angle-right"/></li>
        <li><p:link outcome="/admin/StateList">Lista de Estados</p:link></li>
        <li><i class="fa fa-angle-right"/></li>
        <li><p:link outcome="/admin/StateList">Editar estado</p:link></li>
    </ui:define>

    <ui:param name="viewname" value="Editar Estado"/>


    <ui:define name="content">
        <div class="p-grid form-superfinanciera">
            <div class="p-col-12">
                <div class="card">
                    <p:growl id="messages" showDetail="true" />

                    <h4>Editar Estado</h4>
                    <h:form>
                        <p:growl id="growl" showDetail="true" sticky="true" />
                        <p:outputPanel id="businessProcessContent">
                            <div class="ui-fluid p-formgrid p-grid">

                                <div class="p-field p-col-12 p-md-6">
                                    <p:outputLabel for="name" value="Nombre"/>
                                    <p:inputText id="name" required="true" requiredMessage="Nombre requerido" value="#{stateController.newName}"/>
                                    <p:message for="name" display="icon" />
                                </div>
                            </div>
                        </p:outputPanel>

                        <p:commandButton id="submitButton"
                                         value="Confirmar cambios"
                                         update="businessProcessContent :messages"
                                         process="businessProcessContent @this"
                                         actionListener="#{stateController.updateState()}"
                                        />
                    </h:form>
                </div>
            </div>
        </div>
    </ui:define>

</ui:composition>

StateController.java

@Named
@ViewScoped
public class StateController {

    @Inject
    private StateList stateList;

    @Inject
    private StateStore store;

    @Inject
    private StateDao stateDao;

    @Named
    @Produces
    private State newState;

    @Getter
    @Setter
    private String newName;

    @Getter
    @Setter
    private Long recivedId;

    @Getter
    @Setter
    private Integer searchID;

    @Getter
    @Setter
    private String searchName;

    @PostConstruct
    public void initNewState() {
            this.newState = new State();
    }

    public void initExistentState(){
        try {
            recivedId = Long.valueOf(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id"));
            this.newState = stateDao.getSingle(recivedId);
        }
       catch (Exception ex){
           FacesContext context = FacesContext.getCurrentInstance();
           context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"ERROR",""  ) );
       }
    }


    public void setCurrentState(State state){
        store.set(state);
    }

    public void setStateResults(List<State> stateResults) {
        this.stateResults = stateResults;
    }

    private List<State> stateResults;

    public List<State> getStateResults() {
        if(stateResults==null) {
            stateResults=stateDao.getAll();
        }
        return stateResults;
    }

    public List<State>  getFilteredResults(){
        stateResults= stateDao.getFiltered(searchID,searchName);
        return stateResults;
    }


    public void deleteState(){
        stateDao.delete(stateDao.getSingle(recivedId));
        stateList.invalidate();
        store.unset();

    }

    public void createState() {
        stateList.invalidate();
        stateDao.create(newState);
        store.set(newState);
        initNewState();
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage("Transacción exitosa",  "Se ha guardado el estado") );
    }

    public void updateState(){
        stateList.invalidate();
        State tate = newState;
        newState.setName(newName);
        stateDao.update(newState);
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage("Transacción exitosa",  "Actualizacion completada"));
    }

}

ViewScoped beans 应该实现可序列化,这样它们就可以在同一视图的请求中持久化。否则它们将在每个请求中创建并且表现得像 RequestScoped beans。

您的命令按钮是第二个请求,那里的数据丢失了。您要么使 bean 可序列化,要么将必要的参数添加到命令按钮以使用请求范围。