【问题标题】:Ajax update=":#{table.clientId}" does not seem to work on <p:dataTable>Ajax update=":#{table.clientId}" 似乎不适用于 <p:dataTable>
【发布时间】:2015-12-13 03:02:30
【问题描述】:

我对 PrimeFaces 5.2 和客户端组件更新机制有一些问题

我创建了一个带有触发服务器端方法的按钮的网页。此方法更新对象列表,最后 将使用列表的新内容更新数据表。

<h:form> 
        ...
        <p:commandButton value="Add parameters" action="#{adminBean.addParams}"  
                         update=":growl :#{tblSensors.clientId}"  />
</h:form>

<h:form>
    <p:dataTable id="tblSensors"  
            var="sensorElem" value="#{adminBean.sensors}"
            binding="#{tblSensors}"
        >  
            ...
        </p:dataTable>
</h:form>

不幸的是,当程序回调结束时,我的数据表没有更新..真诚地我无法找到问题。

调试阶段没有异常,我在 Firebug 的响应数据中什么也没看到。

更新:我看到当bean方法被调用并且一些变量已经改变时;这种变化不是持久的,每次调用方法时都会错过它们

更新 2: 根据要求,我添加了 bean 代码:

@ManagedBean(name="adminBean")
@SessionScoped
public class AdminBean implements Serializable{
    private List<Sensor> sensors;


    public List<Sensor> getSensors() {
        return sensors;
    }

    public void setSensors(List<Sensor> sensors) {
        this.sensors = sensors;
    }


    //...




 @PostConstruct
    public void init(){
       //...
        //initialize sensor list
        this.sensors = new ArrayList<Sensor>();

        //...
    }



    //method for adding new sensor
    public void addParams(){


        try{


        //add new sensor element to the list 
        this.sensors.add(new Sensor(this.param_name,Double.parseDouble(this.min_val),Double.parseDouble(this.max_val), 
                this.unit, this.selectedChartType, this.selectedFieldType, id_counter++));





        }catch(Exception e){

            System.out.println("Error "+e.getMessage());
            System.out.println("stack "+e.getStackTrace());
        }

        FacesContext.getCurrentInstance().addMessage(null, 
                new FacesMessage(FacesMessage.SEVERITY_INFO,"Successful", "New sensor added!")); 
    }

    //...

}

更新 3:修复一些命名空间错误。

【问题讨论】:

  • @BalusC : 只是出于好奇,您为什么要更改从我的线程中删除一些元素?
  • @Tiny:好的,我明白了,对不起我的问题
  • 因为它们对实际问题没有贡献。删除它们后,您实际上仍然会遇到完全相同的问题。有关如何提出正确问题的其他提示,另请参阅 stackoverflow.com/tags/jsf/info
  • @BalusC:好的,谢谢BalusC
  • 四个字母:mcve(见How to Ask

标签: jsf jsf-2 primefaces datatable


【解决方案1】:

虽然我对带有数据绑定的dataTables不熟悉,我认为update-statement不正确,您需要在触发commandButton时更新datatable

update=":growl, :tblSensors"

【讨论】:

  • 我必须使用数据绑定,因为我要更新的组件是在 commandButton 声明之后定义的。事实上,如果我尝试你的建议,我会得到带有“找不到表达式组件:tblSensors”的 handlerRenderException。
  • 更新您的数据表周围的&lt;h:form&gt;,使其看起来像&lt;h:form prependId="false"&gt;,然后重试Raphael Roth 的建议。
  • @MathieuCastets:为什么是prependId="false"?我尽量不使用它,因为在 Ajax 调用stackoverflow.com/questions/7415230/… 中仍然需要预先添加这样的“问题”
  • 确实很有趣的链接,谢谢!这只是一个简短的评论,只是为了测试 update 是否适用于正确的组件 ID。然后我会将 OP 重定向到这个答案stackoverflow.com/questions/14438707/…
  • @MathieuCastets:感谢您的支持!当我使用 PrimeFaces 和 JSF 时,我总是使用数据绑定方法,它总是工作正常!我认为问题不在于 prependId 的使用...我看不到问题...:S
【解决方案2】:

为什么不直接指定表单 id 以便更新子元素更直接?试试:

<h:form> 
        ...
        <p:commandButton value="Add parameters" action="#{amminBean.addParams}"  
                         update=":growl :datatableform:tblSensors"  />
</h:form>

<h:form id="datatableform">
    <p:dataTable id="tblSensors"  
            var="sensorElem" value="#{aminBean.sensors}"
            binding="#{tblSensors}">  
            ...
        </p:dataTable>
</h:form>

【讨论】:

  • 很遗憾您的建议并没有解决我的问题(昨天我尝试了您的解决方案,但问题仍然存在)。我认为问题出在bean方法上。在调试模式下,我看到对服务器端属性执行的每个更改都不是持久的,这听起来很奇怪(我使用的是 Session Scoped)。当我通过 commandButton 调用 bean 方法时,我看到它运行良好,但在方法结束时所有数据更改都丢失了。因此 tblSensors 数据表没有新数据
  • 你能发布你的backing bean的相关sn-ps吗?
  • 嗨,'#{amminBean.addParams}' 和 '#{aminBean.sensors}' 只是拼写错误吗?他们应该使用'adminBean'对吗?此外,您的 p:commandButton 正在调用 addParams 方法,但您在支持 bean 中发布的内容名为 addSensor()。
  • 是的,很抱歉,我忘记更改对象名称。
  • 此外,adminBean.sensors 链接到包含我想在 tableView 中显示的信息的 ArrayList,并且 adminBean.addParams 链接到在 ArrayList 中创建和附加新元素的 bean 方法
【解决方案3】:

我解决了更改实现理念的问题:我将选项卡内容划分为 2 个带有相关 bean 的单独 xhtml 文件,第一个用于“父”元素管理,第二个用于其子元素。

所以,第一个 xhtml:

 <h:form> 
     <p:panel id="panel" header="New Station" style="margin-bottom:10px;">
          <h:panelGrid columns="2" cellpadding="5">
          <p:inputText id="stationName" required="true" value="#{adminBean.stationName}"/>
          <p:inputText id="description" required="true" value="#{adminBean.description}" />

          <p:outputLabel value="Station type" for="stationType" />
              <p:selectOneMenu id="stationType" value="#{adminBean.selectedStationType}" >
                  <f:selectItem itemLabel="Select Type" itemValue="-1" noSelectionOption="false" />
                  <f:selectItems value="#{adminBean.stationType}" />
             </p:selectOneMenu>
         </h:panelGrid>
     </p:panel>


    <p:commandButton value="Cancel" action="#{adminBean.cancella}" icon="ui-icon-check"  />

    <p:commandButton value="Next >" id="nextId" binding="#{nextId}"  action="#{adminBean.nextStep}" 
                    icon="ui-icon-check" update=":growl" />
 </h:form>

当用户选择下一个按钮时,将调用一个新页面,其 bean 将使用与第一页相关的 bean 来检索所有需要的信息并正确显示其元数据。

这是第二页:

<h:form> 
   <p:panel id="panel2" header="Aggiungi sensori" style="margin-bottom:10px;">
      <h:panelGrid columns="2" cellpadding="5">


          <p:inputText id="param_name" required="true" value="#{adminSensorsBean.param_name}"/>


          <p:selectOneMenu id="chartType" value="#{adminSensorsBean.selectedChartType}" >
                   <f:selectItem itemLabel="Select Type" itemValue="-1" noSelectionOption="false" />
                   <f:selectItem itemLabel="Line" itemValue="LINE" noSelectionOption="false" />
                   <f:selectItem itemLabel="Bar" itemValue="BAR" noSelectionOption="false" />
                </p:selectOneMenu>
                //...

                <p:selectOneMenu id="fieldType" binding="#{fieldType}" value="#{adminSensorsBean.selectedFieldType}" >
                    <f:selectItem itemLabel="Select Field" itemValue="-1" noSelectionOption="false" />
                    <f:selectItems value="#{adminSensorsBean.fieldsType}" />
                </p:selectOneMenu>

            </h:panelGrid>

            </p:panel>
            <p:commandButton value="Add Sensor" id="addSensorId" binding="#{addSensorId}" 
                             action="#{adminSensorsBean.addSensor}" 
                             icon="ui-icon-check" update=":growl :#{tblSensors.clientId}" />
        </h:form>

        <h:form>
            <p:dataTable id="tblSensors"  
                var="sensorElem" 
                value="#{adminSensorsBean.sensors}"
                scrollable="true"
                rowKey="#{sensorElem.id}"
                binding="#{tblSensors}"
                scrollHeight="150"
            >  
               //...
               //this table will be filled with data from form above
               //...

            </p:dataTable>
        </h:form>


        //...
        <h:form> 
           <p:commandButton value="Submit" id="submitId" binding="#{submitId}" action="#{adminSensorsBean.saveStation}" 
                    icon="ui-icon-check" update=":growl" />
        </h:form>

通过添加传感器按钮,新信息将被调用的bean方法插入到tableView中。

@ManagedBean(name="adminSensorsBean")
@SessionScoped
public class AdminSensorsBean implements Serializable{

//Managed property from bean of first page
@ManagedProperty(value="#{adminBean}")
    private AdminBean adminBean;

 //...

@PostConstruct
public void init(){
    //Here all second page elements as FieldType list, will be initialized using stored information from managed property.

}

//...

}

这样一切正常!老实说,当我将所有代码仅放在一个 jsf 页面中时,我不知道为什么更新事件不起作用。它是 PrimeFaces/JSF 错误吗?也许,但我不确定。 感谢您的支持,对不起我的英语粗鲁

【讨论】:

    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    • 2020-04-04
    • 2023-04-06
    相关资源
    最近更新 更多