使用来自@ManagedBean 的值执行 JS 函数
Execute JS function with value from @ManagedBean
我有一个后端 restservice 调用,返回一个值,我必须用它执行一个 JS 函数(为简单起见,我在前端使用 "alert"。这必须在 JSF 中实现,我很难过。
而且,这就是问题所在,出于性能原因,我希望在单击时执行后端 rest-call。
这是(除其他外)我尝试过的:
<p:commandLink action="#{viewingSessionBean.prepareViewingSession(document)}" oncomplete="alert('#{viewingSessionBean.name(document)}')">
<p:graphicImage value="documentViewerPopup.png"/>
</p:commandLink>
这里是豆子(为了使观点更清楚而缩短):
@ManagedBean
@ViewScoped
public class ViewingSessionBean implements Serializable {
private String name;
public String prepareViewingSession(Document document) {
name = restClient.call()
hashMap.put(document.getBlobId(), name);
return null; // don't navigate away...
}
public String name(Document document) {
return hashMap.get(document.getBlobId()); // return null if nothing is cached for the document yet there
}
}
我想做这样的事情(伪代码...没有h:commandScript...,太旧的JSF,没办法升级)
<h:commandScript action="alert('#{viewingSessionBean.prepareViewingSession(document)}') />
完成起来有点棘手,但仍然可行。
您必须首先牢记一件事:您在 .xhtml 中编写的 JavaScript 代码以 'static' 方式呈现。但是 'static' 是什么意思?这意味着如果您在 JavaScript 代码中引用一个 bean 变量,然后在您的 bean 中更新这个变量值,您打印的 JavaScript 代码将无法看到您刚刚所做的这些更改。在这种情况下,您必须首先更新 JavaScript 代码(使用 ajax)以获取变量中的更改,然后才执行它。
让我们从您的 bean 开始:
@ManagedBean
@ViewScoped
public class ViewingSessionBean implements Serializable {
private String variable;
public String getVariable() {
return this.variable;
}
public void updateVariableValue(Document document) {
variable = restClient.call();
}
}
现在,.xhtml代码:
<h:form id="form">
<p:commandLink id="firstLink"
actionListener="#{viewSessionBean.updateVariableValue(document)}"
update=":form:secondLink"
oncomplete="$('#form\:secondLink').click()"/>
<p:commandLink id="secondLink" onclick="alert('#{viewSessionBean.variable}')" style="display: none;"/>
</h:form>
注意几点:
第一:使用了两个命令Link,而不是一个,为什么?因为在第一个 Link 的 oncomplete 调用时,bean 变量已经是最新的,但是您的 html 代码不是。因此,为了获得 bean 变量的更新值,我们执行以下操作:
- 调用actionListener更新bean上的变量值;
- 在第二个 Link 上进行 ajax 更新以从 bean 获取更新后的值;
- 调用 oncomplete 方法并点击第二个 Link(现在更新为正确的值);
第二:要调用第二个 Link 的点击,我们必须转义 jQuery 调用中的两个点。
第三:第二个Link设置了display:none样式,使其在屏幕中不可见。
现在只是一些关于它的想法:JSF 与 JavaScript 一起工作得很好,但有时我们必须像这样使用一些笨拙的技巧来完成 "easy" 任务。我并不是说 JSF 不好,但我认为我们可以有更多 'out-of-box' 的方法来处理这类事情。不过只是我的意见。
我有一个后端 restservice 调用,返回一个值,我必须用它执行一个 JS 函数(为简单起见,我在前端使用 "alert"。这必须在 JSF 中实现,我很难过。
而且,这就是问题所在,出于性能原因,我希望在单击时执行后端 rest-call。
这是(除其他外)我尝试过的:
<p:commandLink action="#{viewingSessionBean.prepareViewingSession(document)}" oncomplete="alert('#{viewingSessionBean.name(document)}')">
<p:graphicImage value="documentViewerPopup.png"/>
</p:commandLink>
这里是豆子(为了使观点更清楚而缩短):
@ManagedBean
@ViewScoped
public class ViewingSessionBean implements Serializable {
private String name;
public String prepareViewingSession(Document document) {
name = restClient.call()
hashMap.put(document.getBlobId(), name);
return null; // don't navigate away...
}
public String name(Document document) {
return hashMap.get(document.getBlobId()); // return null if nothing is cached for the document yet there
}
}
我想做这样的事情(伪代码...没有h:commandScript...,太旧的JSF,没办法升级)
<h:commandScript action="alert('#{viewingSessionBean.prepareViewingSession(document)}') />
完成起来有点棘手,但仍然可行。
您必须首先牢记一件事:您在 .xhtml 中编写的 JavaScript 代码以 'static' 方式呈现。但是 'static' 是什么意思?这意味着如果您在 JavaScript 代码中引用一个 bean 变量,然后在您的 bean 中更新这个变量值,您打印的 JavaScript 代码将无法看到您刚刚所做的这些更改。在这种情况下,您必须首先更新 JavaScript 代码(使用 ajax)以获取变量中的更改,然后才执行它。
让我们从您的 bean 开始:
@ManagedBean
@ViewScoped
public class ViewingSessionBean implements Serializable {
private String variable;
public String getVariable() {
return this.variable;
}
public void updateVariableValue(Document document) {
variable = restClient.call();
}
}
现在,.xhtml代码:
<h:form id="form">
<p:commandLink id="firstLink"
actionListener="#{viewSessionBean.updateVariableValue(document)}"
update=":form:secondLink"
oncomplete="$('#form\:secondLink').click()"/>
<p:commandLink id="secondLink" onclick="alert('#{viewSessionBean.variable}')" style="display: none;"/>
</h:form>
注意几点:
第一:使用了两个命令Link,而不是一个,为什么?因为在第一个 Link 的 oncomplete 调用时,bean 变量已经是最新的,但是您的 html 代码不是。因此,为了获得 bean 变量的更新值,我们执行以下操作:
- 调用actionListener更新bean上的变量值;
- 在第二个 Link 上进行 ajax 更新以从 bean 获取更新后的值;
- 调用 oncomplete 方法并点击第二个 Link(现在更新为正确的值);
第二:要调用第二个 Link 的点击,我们必须转义 jQuery 调用中的两个点。
第三:第二个Link设置了display:none样式,使其在屏幕中不可见。
现在只是一些关于它的想法:JSF 与 JavaScript 一起工作得很好,但有时我们必须像这样使用一些笨拙的技巧来完成 "easy" 任务。我并不是说 JSF 不好,但我认为我们可以有更多 'out-of-box' 的方法来处理这类事情。不过只是我的意见。