未使用AJAX更新JSF视图

未使用AJAX更新JSF视图,ajax,jsf-2,primefaces,Ajax,Jsf 2,Primefaces,我正在尝试使用JSF2.2和PrimeFaces4.0创建一个可更新的GUI。我的问题是模型更新了,但视图没有更新 这是我的示例页面。它只有一个按钮,可以使两个面板改变位置: <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui"> <h:head/> <h:body>

我正在尝试使用JSF2.2和PrimeFaces4.0创建一个可更新的GUI。我的问题是模型更新了,但视图没有更新

这是我的示例页面。它只有一个按钮,可以使两个面板改变位置:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui">
    <h:head/>
    <h:body>
        <h:form>
            <p:panelGrid id="grid">
                <p:row>
                    <p:column id="slot1" style="width: 100px; height: 100px">
                        <p:panel id="panel1" binding="#{test.panel1}" style="width: 100px; height: 100px"/>
                    </p:column>
                    <p:column id="slot2" style="width: 100px; height: 100px">
                        <p:panel id="panel2" binding="#{test.panel2}" style="width: 100px; height: 100px"/>
                    </p:column>
                </p:row>
            </p:panelGrid>

            <p:commandButton id="button2" value="Switch Panels">
                <p:ajax listener="#{test.onSwitchPanels(event)}" update="grid"/>
            </p:commandButton>
        </h:form>
    </h:body>
</html>
调试显示,单击按钮时,getter和setter在
onSwitchPanels()
之后使用正确的新值被调用。 但正如我所写的,视图没有更新。这只有在手动刷新页面或下一次单击后才会发生(这当然会将模型设置回其原始状态,但会显示切换的面板)。
我已经试过
update=“@form”
update=“slot1 slot2”
但运气不好…

我对我的JSF/PF有些生疏,但你试过:

update="panel1 panel2"
另一个尝试是使用

actionListener"#{test.onSwitchPanels}"
而不是

listener="#{test.onSwitchPanels(event)}"

为什么不从onSwitchPanels()方法中删除“event”参数?你没有以任何方式使用它。你可以用枪射击

<p:commandButton id="button2" value="Switch Panels" action="#{test.onSwitchPanels}" update="grid" />

该代码实际上是一个WTF。将UI组件实例绑定到会话范围的bean会带来麻烦。UI组件实例即为请求范围

即使使用了请求范围的bean,如果不重新构建视图,这也不起作用。UI组件树是在构建视图期间创建的。在构建视图之后,您正在操作组件引用,并期望这些更改神奇地反映在UI组件树中。事实并非如此。只有它们的属性才会被反映(因此,当您这样做时,例如
panel1.setHeader(panel2.getHeader())
,反之亦然,那么它就会“起作用”

现在还不完全清楚您为什么会朝这个方向思考。通常,您应该动态地操作模型,而不是视图(UI组件不代表模型,它们代表视图;将它们作为模型/控制器的属性并不能神奇地使其成为模型)。最简单的方法之一是拥有一个实体列表,并以动态的
而不是硬编码的
的形式显示它们,从而根据当前迭代的模型项动态设置所需的组件属性

例如,这个

<h:form>
    <p:dataGrid value="#{bean.items}" var="item" columns="2">
        <p:column><p:panel header="#{item.header}" /></p:column>
    </p:dataGrid>
    <p:commandButton value="swap" action="#{bean.swap}" update="grid" />    
</h:form>
类只是一个带有
属性的javabean。一般的IDE可以自动生成整个类

另见:

我找到了一个采用此示例的解决方案:

主要的一点是以编程方式创建组件。在JSF页面中,我只编写了类似于
的内容,并使用bean使用
Application.createComponent()
创建行、列和面板。然后在事件后再次添加面板


因此,BalusC当然是对的,操作必须在模型中进行。

我尝试了第一个,但没有成功。第二个在
p:ajax
中是不可能的。据我所知,在JSF2.2/Primefaces 4中,您不再需要手动指定p:ajax,所有支持ajax的组件都可以直接更新其他组件。看看这里:啊,好的。所以我尝试了
,但结果是一样的。(对于属性
更新
,我也尝试了
@form
slot1 slot2
panel1 panel2
)啊,我记得不久前我遇到了类似的问题。这与涉及“form”的生命周期有关(本质上是表单提交本身或其他东西并错误地刷新页面)。我没有带代码来查看我是如何修复它的,但有三件事你可以在我的头顶上尝试:1.添加“id='myform'”到表单标签并获取更新以更新“myform”,2.创建一个新表单,并在不同的表单中使用“grid”和“button”,3.将表单包装在一个面板中并更新整个面板。如果这些都不起作用,我将在今晚挖掘我的旧代码!非常感谢!我尝试了所有三个技巧,但都没有成功:(如果你能找到你的解决方案,那就太好了……非常感谢。我只是在做原型。我的问题是,仅仅改变一些属性是不够的。我希望能够有一个带有图表的面板,一个带有一些文本和一些自写组件的面板,可以在网格中自由地重新排列。如果可以的话只需要重新加载视图就可以了。但也许JSF对我的用例来说并不合适……如果你想有条件地构建视图而不是有条件地呈现视图,那么就抓取JSTL。只是想知道,因为我的答案是1-2天内选择的:我的解决方案对你有用吗?
<h:form>
    <p:dataGrid value="#{bean.items}" var="item" columns="2">
        <p:column><p:panel header="#{item.header}" /></p:column>
    </p:dataGrid>
    <p:commandButton value="swap" action="#{bean.swap}" update="grid" />    
</h:form>
private List<Item> items; // +getter

@PostConstruct
public void init() {
    items = new ArrayList<>();
    items.add(new Item("Panel 1"));
    items.add(new Item("Panel 2"));
}

public void swap() {
    items.add(items.remove(0)); // Note: works only if you've only 2 items ;)
}