jsf.ajax.addOnEvent 只有在我明确包含 javax.faces:jsf.js 时才有效

jsf.ajax.addOnEvent works only if I explicitly include javax.faces:jsf.js

我在 head 标签中使用 JSF 2.2.4:

<h:outputScript library="javax.faces" name="jsf.js" />

后来我发现下面post并删除了上面的代码,因为它会自动包含: renaming jsf.js.jsf to jsf.js.xhtml

当我检查时发现它是按照所说自动包含的,但我们在使用放置在通用模板头部的脚本时遇到错误。错误是脚本将 object jsf 作为 undefined。此脚本的目的是为所有 JSF AJAX 调用显示一个通用加载程序。脚本如下:

//To display loading indicator for all JSF f:ajax calls.
jsf.ajax.addOnEvent(function(data) {
  var ajaxstatus = data.status; // Can be "begin", "complete" and "success"
  switch (ajaxstatus) {
    case "begin": // This is called right before ajax request is been sent.
      wizShowAjaxLoader();
      break;
    case "complete": // This is called right after ajax response is received.
      wizHideAjaxLoader();
      break;
    case "success": // This is called when ajax response is successfully processed.
      // NOOP.
      break;
  }
});

我想知道为什么当我明确包含 jsf.js 时它会起作用。当我删除它时,脚本将 jsf 对象显示为未定义。

您需要确保在 javax.faces:jsf.js 被包含后调用您的脚本,原因很简单,jsf 仅定义在JavaScript 范围,当 javax.faces:jsf.js 已包含(并执行)时。

简而言之,您需要确保 JavaScript 代码流程如下所示:

var jsf = ...;
...
jsf.ajax.addOnEvent(...);

所以不是这样的:

jsf.ajax.addOnEvent(...);
...
var jsf = ...;

确保这一点的一种方法是将您的脚本作为 <h:outputScript> 包含在 <h:body> 中,并将 target 设置为 head

<h:head>
    ...
</h:head>
<h:body>
    <h:outputScript name="yourscript.js" target="head" />
    ...
</h:body>

JSF 将确保它最终出现在 HTML 头部 之后 自动包含的脚本。

另一种方法是将其保留在 <h:head> 中,但将 target 设置为 body

<h:head>
    ...
    <h:outputScript name="yourscript.js" target="body" />
</h:head>

JSF 将确保它在 HTML 主体的最后结束,因此它基本上在 DOM 加载事件之前执行。