未调用JSF操作方法 [英] JSF Action Method not being called

查看:134
本文介绍了未调用JSF操作方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有Primefaces数据表的JSF视图,并在其中有一个命令按钮,如下所示:

I have a JSF view with a Primefaces data table and a command button insite it, as fallows:

<p:messages id="statusMessages" showDetail="true" />
    <h:form id="listForm">
        <p:panel header="Wellsite List">
            <br />
            <h:outputLabel value="Welcome, #{wellsiteController.loggedUser.login}" />
            <br />
            <br />

            <p:dataTable id="dataTable" var="wellsite" value="#{wellsiteController.wellsiteDataTableModel}"
                         paginator="true" rows="10" selection="#{wellsiteController.wellsite}">

                <p:column selectionMode="single" style="width:18px" id="radioSelect" />

                <p:column sortBy="#{wellsite.reference}" headerText="Wellsite ID">
                    <h:outputText value="#{wellsite.reference}" />
                </p:column>

                <p:column headerText="Allowed Groups">
                    <h:outputText value="#{wellsite.allowedGroups.toString()}" />
                </p:column>

                <f:facet name="footer">
                    <h:panelGrid columns="3">
                        <p:commandButton id="addWellsite" value="Add New Wellsite" icon="ui-icon-flag" ajax="false" action="#{wellsiteController.showAddWellsite}"/>
                        <p:commandButton id="editWellsite" value="Edit Selected Wellsite" icon="ui-icon-wrench" ajax="false" action="#{wellsiteController.showEditWellsite}"/>

                        <p:commandButton id="deleteWellsiteButton" value="Remove Selected Wellsite" icon="ui-icon-trash" onclick="confirmation.show()" type="button"/>

                    </h:panelGrid>
                </f:facet>
            </p:dataTable>
            <p:spacer height="20" />
        </p:panel>
        <p:confirmDialog id="confirmDialog" message="Are you sure you want to remove the selected Wellsite along with all it's data?" header="Confirmation" severity="alert" widgetVar="confirmation">  
            <p:commandButton id="confirm" value="Yes" ajax="false" oncomplete="confirmation.hide()" action="#{wellsiteController.deleteWellsite}" />
            <p:commandButton id="decline" value="Cancel" onclick="confirmation.hide()" type="button" />   

        </p:confirmDialog>
    </h:form>

这是控制器:

@ManagedBean(name = "wellsiteController")
@RequestScoped
public class WellsiteController implements Serializable {
private static final long serialVersionUID = 1L;

@ManagedProperty("#{wellsiteDao}")
private WellsiteDao wellsiteDao;

@ManagedProperty("#{userDao}")
private UserDao userDao;

@ManagedProperty("#{groupDao}")
private GroupDao groupDao;

@ManagedProperty("#{userController.loggedUser}")
private UserEnt loggedUser;

private WellsiteEnt wellsite;
private List<WellsiteEnt> wellsiteList;
DualListModel<GroupEnt> pickGroupsModel;

public WellsiteController(){
}

@PostConstruct
public void build(){
    wellsite = new WellsiteEnt();
    wellsite.setAllowedGroups(new ArrayList<GroupEnt>());
}

/*some getters & setters*/

public WellsiteDataTableModel getWellsiteDataTableModel(){
    return new WellsiteDataTableModel(getWellsiteList());
}

public void setPickGroupsModel(DualListModel<GroupEnt> model){
    pickGroupsModel = model;
}

public DualListModel<GroupEnt> getPickGroupsModel() {
    if(pickGroupsModel == null){
        List<GroupEnt> allGroups = groupDao.getAll();
        List<GroupEnt> currentGroups = wellsite.getAllowedGroups();
        for(GroupEnt g : currentGroups){
            allGroups.remove(g);
        }
        pickGroupsModel = new DualListModel<GroupEnt>(allGroups, currentGroups);
    }
    return pickGroupsModel;
}

public String listWellsites(){
    getWellsiteList();
    return "listWellsites";
}

public String showAddWellsite(){
    FacesContext context = FacesContext.getCurrentInstance();
    setWellsite(new WellsiteEnt());
    wellsite.setAllowedGroups(new ArrayList<GroupEnt>());
    pickGroupsModel = null;
    context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO,
                                            "Fields annotated with a ' * ' are mandatory",""));
    return "addWellsite";
}

public String addWellsite(){
    FacesContext context = FacesContext.getCurrentInstance();

    wellsite.setDate(new Date());
    wellsite.setLastUpdate(wellsite.getDate());
    try {
        wellsiteDao.addWell(wellsite);

        for(GroupEnt g : pickGroupsModel.getTarget()){
            GroupEnt group = groupDao.getOne(g.getGroupId());
            group.getGroupWellsites().add(wellsite);
            groupDao.update(group);
        }
        return listWellsites();

    } catch (Exception ex) {
        Logger.getLogger(WellsiteController.class.getName()).log(Level.SEVERE, null, ex);
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,
                                            ex.getMessage(),""));
        return null;
    }
}
}

此视图正确呈现.数据表和按钮看起来不错.问题是,当我第一次单击"addWellsite"命令按钮时,什么也没发生.该页面似乎只是刷新.如果我再次单击它,则发生异常:

This view gets rendered correctly. The datatable and buttons looks fine. The problem is that when first i click the "addWellsite" commandButton, nothing happens. The page just seems to refresh. If i click it again, as exception happens:

java.lang.NumberFormatException: For input string: "null"

使用调试器,我发现第一次没有调用"addWellsite"的动作,因此,不会生成任何结果(因此,页面刷新).

Using a debugger, i found out that the "addWellsite"'s action is NOT called the first time, and so, not outcome is generated (thus, the page refresh).

该异常可能是由于当前视图或目标视图中缺少初始化而造成的(因为这两个视图都是通过页面刷新中未调用的操作方法显示的)

The exception is probably comming from the lack of initialization in the current or the target views (since both view are displayed from action methods that were not called in the page refresh)

问题是:为什么不第一次调用该操作方法?

此答案:

只要UICommand组件未能调用关联的操作,请验证以下内容:

Whenever an UICommand component fails to invoke the associated action, verify the following:

  1. UICommand组件必须放置在UIForm组件(例如h:form)内部.
  1. UICommand components must be placed inside an UIForm component (e.g. h:form).

我确实有一个h:form

I do have a h:form

  1. 您不能互相嵌套多个UIForm组件(当心包含文件!).
  1. You cannot nest multiple UIForm components in each other (watch out with include files!).

只有一个.

  1. 应该不会发生任何验证/转换错误(使用h:messages可以全部获取).
  1. No validation/conversion error should have been occurred (use h:messages to get them all).

我有一个不会显示任何错误的h:messages.

I have a h:messages that does not display any error.

  1. 如果将UICommand组件放置在UIData组件内部,请确保保留完全相同的DataModel(UIDatavalue属性后面的对象).
  1. If UICommand components are placed inside an UIData component, ensure that exactly the same DataModel (the object behind the UIData's value attribute) is preserved.

commandButton在dataTable内部,但是目标视图不需要dataModel.如我的控制器代码所示,该对象是在视图尝试检索它时生成的.下一个请求不使用此dataTable,我不再处理它.

The commandButton is inside the dataTable, but the target view does not need the dataModel. As my controller code shows, the object is built as the view tries to retrive it. The next request is not using this dataTable, to i do not handle it anymore.

  1. 该组件以及所有父组件的rendereddisabled属性在应用请求值阶段不应评估为false.
  1. The rendered and disabled attributes of the component and all of the parent components should not evaluate to false during apply request values phase.

没有rendereddisbled属性.

  1. 请确保请求-响应链中没有任何PhaseListener或任何EventListener更改了JSF生命周期以跳过调用操作阶段.
  1. Be sure that no PhaseListener or any EventListener in the request-response chain has changed the JSF lifecycle to skip the invoke action phase.

未定义phaseListener.

No phaseListener is defined.

  1. 请确保同一请求-响应链中没有FilterServlet阻止了FacesServlet的请求.
  1. Be sure that no Filter or Servlet in the same request-response chain has blocked the request fo the FacesServlet somehow.

未定义其他Servlet.我什至都不知道过滤器是什么.

No other Servlet is defined. I don't even know what a Filter is.

为什么不第一次调用该操作方法?

推荐答案

当预先由另一个 <h:form>发起的ajax请求呈现了该<h:form>的父级时,可能会发生这种情况.然后,渲染/更新的<h:form>将丢失其视图状态.这是由 JSF问题790 中所述的JavaScript API中的错误引起的已针对即将推出的JSF 2.2进行了修复.

This can happen when a parent of this <h:form> was been rendered by an ajax request initiated by another <h:form> beforehand. The rendered/updated <h:form> would then lose its view state. This is caused by a bug in the JavaScript API as described in JSF issue 790 which is already fixed for the shortly upcoming JSF 2.2.

同时,对于JSF 2.0/2.1,您需要以另一种形式在操作的render(或对于PrimeFaces,update)属性中明确指定<h:form>的客户机ID.

In the meanwhile, with JSF 2.0/2.1, you need to explicltly specify the client ID of the <h:form> in the render (or for PrimeFaces, the update) attribute of the action in the other form.

例如

<h:commandButton ...>
   <f:ajax ... render=":listForm" />
</h:commandButton>

<p:commandButton ... update=":listForm" />

或者只是将其设为普通(非ajax)请求.

Or just make it a normal (non-ajax) request instead.

这篇关于未调用JSF操作方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆