我有一个自定义组件(即一个xitml文件,其中包含ui:composition),我有一个文件上传字段。选择文件后,它会通过AJAX上传
<uc:fileUpload
id="#{id}fileUploadComponent"
idSuffix="#{id}fileUploadSuffix"
value="#{fileUpload.docsFilePart}"
accept="#{fieldWrapper.acceptedFileTypes}"
widgetVar="#{id}documentUploadWidget"
nullAllowed="#{!((fieldDef.mandatory and
fieldWrapper.getCurrentFileCount() lt 1) and isSaving)}"
maxSize="#{customField.maxFileSize}" >
<f:ajax listener="#{fileUpload.uploadNewFile(fieldWrapper)}" render="#{localId}fileUploadMain messages"/>
</uc:fileUpload>
在这个上传下面有一个<div>
,它具有与ajax调用的render
属性中指定的相同的id,其中显示了用于下载文件的链接。发生的事情很奇怪 - 在选择文件后,上传,<div>
正确更新,并带有新上传文件的链接。但是,当我点击页面上的“取消”或“保存”时,会调用他们的相应操作,将正确的响应返回给浏览器(状态为200),但浏览器似乎忽略它 - 页面没有直观更新或任何内容...
自定义组件是相当大的代码片段,不易重写的逻辑,所以在这一点上替换它将是......很难......
有一件事可能不是上传文件发生在一个单独的控制器,而主页面控制器是另一个。这是因为单独的控制器应该处理来自自定义组件的上载。
我无法真正理解究竟发生了什么,更不用说为什么,我会感激任何想法!
为了它的价值,我在Wildfly 11上使用Mojarra(AS提供的那个)
事实证明,原因是通过JSF AJAX上传文件会导致创建名为“JSFFrameId”的iframe,并将该帧设置为嵌套表单的目标。在AJAX请求完成后,目标未被删除/清除,从而导致响应进入该iframe并破坏视图。在这一点上,我不确定是什么导致这种情况,但对我而言,解决方法是在onevent
定义中使用<f:ajax>
,清除表单目标,如下所示:
<f:ajax
listener="#{fileUpload.uploadNewFile(fieldWrapper)}"
onevent="function(e){if (e.status == 'complete') { $(e.source).parents('form').attr('target','');}"
render="#{localId}fileUploadMain messages">
我将检查其他州可能需要处理的内容,但基本上这可以解决问题。如果有人对可能导致JSF留下这个iframe的内容分享他们的怀疑而不重置表单的目标可能会有用。