【问题标题】:Conditionally invoking JavaScript from a bean从 bean 有条件地调用 JavaScript
【发布时间】:2013-03-07 18:55:47
【问题描述】:

如何在 JSF 2 中从 bean 有条件地调用 JavaScript?

我有一个使用 PrimeFaces 的类,它将用户文件上传到特定文件夹,但是如果用户尝试上传与已经存在的文件同名的文件,我希望 JavaScript 在这种情况下打开一个框在屏幕上询问用户是否要覆盖旧文件或取消操作。如果不存在具有该名称的文件,则不调用 JavaScript。

我知道如何测试文件夹中是否包含特定文件,只是我需要知道如何有条件地调用 JavaScript。

如果有任何建议,我将不胜感激。


我在网上查看了各种资源,但仍然无法让应用程序正常工作。基本上,这就是我所做的,在包含的 xhtml 页面中,我有以下文件上传代码:

<p:fileUpload id="fileUpload" fileUploadListener="#{filters.upload}"
   allowTypes="#{filters.uploadTypes}" invalidFileMessage="#{filters.uploadBadType}"
   sizeLimit="#{filters.uploadSize}" invalidSizeMessag="#{filters.uploadBadSize}"
   update="fileUpload fileTable uploadMessage" description="Select Text File"
   disabled="#{filters.disableFileUploadButton}"/>

<!--- Then further in the same file is this: -->

<p:remoteCommand name="remoteCommandOverwrite" actionListender="#{filters.execOverwrite}"/>

包含上述内容的父 xhtml 页面我有愚蠢的 JavaScript:

<script type="text/javascript">
  function popupConfirm() {
    var overwrite = confirm('Warning: This will overwrite the existing file - Do you confirm this?');
    if (overwrite) remoteCommandOverwrite([{name: overwrite, value: true}]);
  }
</script>

在我的 bean 中,我有以下三种方法的代码:

    public void upload(FileUploadEvent event) {
    FacesMessage msg = new FacesMessage("Success! ", event.getFile().getFileName() + " is uploaded.");  
    FacesContext.getCurrentInstance().addMessage(null, msg);
    overwrite = false;
    // Do what you want with the file        
    try {
        copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

    public void copyFile(String fileName, InputStream in) {

     // Initialization etc.

                    File file = new File(uploadFull + fileName);
        if (file.exists()) {
            RequestContext.getCurrentInstance().execute("popupConfirm()");

// Then test to see if overwrite is true or false, and act accordingly

}

// Then I am supposed to get the value of overwrite here:
public void execOverwrite() {
    System.out.println("### execOverwrite() ###");
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> map = context.getExternalContext().getRequestParameterMap();
    String soverwrite = (String) map.get("overwrite");
    if (soverwrite.equals("true")) {
        overwrite = true;
        System.out.println("overwrite: true");
    }
}

我要做的是首先有条件地调用 JavaScript 函数 popupConfirm()。如果代码为真,则单击“上传”按钮,这就是我想要的。然后应该调用

这有效并打开了确认()框,但从未调用过,因此我的 bean 中的方法 execOverwrite() 也从未被调用过,我无法获取返回值并将其传递给方法复制文件()。出了什么问题?


我把这个问题搁置了大约一个星期,然后才重新开始。我让它工作,并且可以将一个值传回 bean,但不知何故我需要从调用 JavaScript 的地方恢复执行。

总而言之,我的 JavaScript 包含以下代码:

<script type="text/javascript">
  function popupConfirm() {
    var overwrite = confirm('Warning: This will overwrite the existing file - Do you confirm this?');
    if (overwrite) remoteCommandOverwrite([{name: 'overwrite', value: 'true'}]);
  }
 </script>

在我的 xhtml 代码中:

<p:fileUpload id="fileUpload" fileUploadListener="#{filters.upload}" ...../>

<!-- Other code -->

<p:remoteCommand name="remoteCommandOverwrite" actionListener="#{filters.execOverwrite}"/>

然后在单击选择文件按钮后单击文件上传按钮,执行上面列出的 JavaScript 中的代码:

RequestContext.getCurrentInstance().execute("popupConfirm()");

然后点击对话框中的“确定”,调用同一个bean中的这个方法:

public void execOverwrite() {
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> map = context.getExternalContext().getRequestParameterMap();
    String soverwrite = map.get("overwrite");
    if (soverwrite.equals("true")) {
        overwrite = true;       }
    }
}

最终将测试“覆盖”标志是否为真。

我使用各种打印语句检查它是否有效。但是,代码在遇到以下语句后并没有恢复执行:RequestContext.getCurrentInstance().execute("popupConfirm()");无论我在对话框中输入“确定”还是“取消”,这都是我想要它做的。看起来好像需要某种类型的回调,并且非常感谢一些想法。

【问题讨论】:

  • 我对 Primefaces 5.1 和 JSF 2.2.6 有同样的问题。 .你有解决办法吗?

标签: javascript jsf primefaces


【解决方案1】:

根据您的标签,您使用的是 PrimeFaces,因此当浏览器完成对服务器响应的处理时,有一种简单的方法可以从服务器端事件托管 bean 方法调用 javascript 函数。 PrimeFaces 为您提供了一个名为 RequestContext 的实用程序类。

public void doActionListenerMethod() {
  if (!isValid()) {
    RequestContext.getCurrentInstance().execute("MyJSObject.doClientSideStuff()");
  }
}

当 JSF 在客户端完成渲染时,以下将作为 Javascript 执行字符串参数。

【讨论】:

  • 好的,非常感谢,我可以使用一个简单的 alert() 框来快速测试。现在我需要使用出现的确认()框,并根据用户是单击“确定”还是“取消”,上传文件或取消上传。不知何故,这必须从 JavaScript 传递回 bean。
  • @csharp 好吧,如果您使用 PrimeFaces 对话框,那么您可以指定一个 widgetVar,它是一个 Javascript 变量,它们还有一个用于客户端的 show()hide() 函数。老实说,我可能会立即将文件上传到会话变量中,以便它位于服务器内存中。然后,我将在对话框内的一个表单中,将 OK 和 Cancel 按钮作为 JSF commandButtons 调用服务器事件来保存文件或在取消时从会话上下文中丢弃它。 &lt;p:commandButton&gt;oncomplete属性可以调用hide()JS函数
  • 好的,这很有帮助,但我想让它尽可能简单。如何从 RequestContext.getCurrentInstance().execute("confirm('Warning: 这将删除所有上传的文件 - 你确认吗?')"); “confirm()”框打开的位置,然后根据用户的回复方式,返回 true 或 false。如何从 RequestContext 中获取返回值然后采取相应的行动?
  • @csharp 您必须编写一个 Javascript 函数来调用确认框,然后根据用户结果调用 p:remoteCommand。有关如何使用 remoteCommand 尽可能简单地执行此操作的示例,请参阅 here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-13
  • 2016-02-15
  • 1970-01-01
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多