我知道在asp.net中有一个属性(可能是"<%@ Page%>标签的EnableEventValidation) .哪一个,当我尝试使用javascript将选择项添加到组件时,一旦造成问题,我想知道jsf如何处理这个。也就是说,
如果我像下面这样发送一个h:select*并且客户端添加一个新项目"option3"到项目列表,JSF是否会在更新模型值之前自动检测到这个?
<h:selectOneMenu id="type"
value="#{foo.value}"
required="true"
requiredMessage="Type is required"
style="width:100px">
<f:selectItem value="option1}"/>
<f:selectItem value="option2}"/>
</h:selectOneMenu>
我认为关于JSF,您需要了解的是组件的客户机/服务器部分是紧密耦合在一起的。你可能最好把它们严格地看作一个实体,忘记只摆弄一边,当这是唯一的解决方案时,恢复到自定义Javascript。
另一种思考方式是服务器端呈现客户端,而不是相反!因此,无论何时你需要更新组件,更新必须首先在服务器端完成,它将传播到客户端(浏览器)。
在您的示例中,向select*
项添加元素的正确方法是将可选项存储在bean(可能是@ViewScoped
)中的数据结构中,然后通过AJAX对select*
组件或其容器组件进行部分更新,当服务器端有机会意识到更改并可以正确更新客户端时。
当然,您可以仅通过Javascript破解,但是为什么要使用JSF呢?JSF的全部意义在于避免需要这样的攻击。
请记住,JSF不是JSP, JSP基本上是用于html输出的println宏。JSF将页面组件的表示存储在服务器端,镜像浏览器的表示。
查看Primefaces展示中有关如何进行部分更新的示例。更具体地说,这就是你要找的例子。这在标准JSF2中是可用的,对于JSF 1.2,必须使用组件库来获得AJAX支持。
您不应该通过JavaScript添加新选项,而应该通过JSF添加新选项。JSF需要以某种方式了解新选项,以便允许提交的值。新的选项真的需要由<f:selectItem(s)>
服务。否则,在提交由JS添加的选项值时,您将始终面临Validation error: Value not valid
。毕竟,这只是JSF的一种保护措施,以防止客户机操纵请求并提交它们不应该提交的值。
下面的启动示例应该可以工作:
<h:form>
<h:selectOneMenu id="menu" value="#{bean.item}">
<f:selectItems value="#{bean.items}" />
</h:selectOneMenu>
<h:inputText id="newItem" value="#{bean.newItem}" />
<h:commandButton value="add" action="#{bean.addNewItem}">
<f:ajax execute="@this newItem" render="menu" />
</h:commandButton>
<h:commandButton value="submit" action="#{bean.submit}" />
</h:form>
与@ViewScoped
管理bean类似:
private String item;
private List<String> items = Arrays.asList("option1", "option2");
private String newItem;
public void addNewItem() {
items.add(newItem);
}
// ...