如何使用 o:deferredScript 延迟 PrimeFaces.settings 和客户端验证脚本
How to defer PrimeFaces.settings and Client Side Validation scripts with o:deferredScript
我正在尝试使用 OmniFaces 来推迟 PrimeFaces 脚本,如 answer.
中所示
但是 PrimeFaces 在 head 中渲染了一个内联脚本,就像这样(我对脚本进行了美化和评论):
<script type="text/javascript">
if(window.PrimeFaces) {
// this line is always rendered in Development mode.
PrimeFaces.settings.projectStage='Development';
// these lines are added if Client Side Validation is enabled.
PrimeFaces.settings.locale='pt_BR';
PrimeFaces.settings.validateEmptyFields=true;
PrimeFaces.settings.considerEmptyStringNull=true;
}
</script>
当我 运行 应用程序时,出现一些 JS 错误(文件和错误):
validation.js.xhtml?ln=primefaces&v=5.3:1
Uncaught TypeError: Cannot read property 'en_US' of undefined
beanvalidation.js.xhtml?ln=primefaces&v=5.3:1
Uncaught TypeError: Cannot read property 'en_US' of undefined
produto.xhtml:2
Uncaught TypeError: Cannot set property 'locale' of undefined
如果我把一些变量放在 primefaces.deferred.js
中,像这样:
if (!primeFacesLoaded) {
window.PrimeFaces = {
// variables added - begin
settings: {
projectStage: 'Development',
locale: 'pt_BR',
validateEmptyFields: true,
considerEmptyStringNull: true
},
// variables added - end
ab: function () {
defer("ab", arguments);
},
cw: function () {
defer("cw", arguments);
},
focus: function () {
defer("focus", arguments);
}
};
}
前两个错误仍然出现,但第三个错误消失了。
显然,PrimeFaces JS 对象缺少以下属性:
locales: {
// other values...
en_US: {
// other values...
}
},
util: {
// other values...
},
所以,问题是:如何正确延迟这些 PrimeFaces 脚本属性?
P.S:版本:PrimeFaces 5.3、OmniFaces 2.3、Payara Server (Glassfish) 4.1.1.161
PrimeFaces.settings
是在 the answer 发布后引入的。同时更新了答案以考虑到这一点。更新后的脚本是:
DeferredPrimeFaces = function() {
var deferredPrimeFaces = {};
var calls = [];
var settings = {};
var primeFacesLoaded = !!window.PrimeFaces;
function defer(name, args) {
calls.push({ name: name, args: args });
}
deferredPrimeFaces.begin = function() {
if (!primeFacesLoaded) {
settings = window.PrimeFaces.settings;
delete window.PrimeFaces;
}
};
deferredPrimeFaces.apply = function() {
if (window.PrimeFaces) {
for (var i = 0; i < calls.length; i++) {
window.PrimeFaces[calls[i].name].apply(window.PrimeFaces, calls[i].args);
}
window.PrimeFaces.settings = settings;
}
delete window.DeferredPrimeFaces;
};
if (!primeFacesLoaded) {
window.PrimeFaces = {
ab: function() { defer("ab", arguments); },
cw: function() { defer("cw", arguments); },
focus: function() { defer("focus", arguments); },
settings: {}
};
}
return deferredPrimeFaces;
}();
基本上,只需将属性准备为一个空对象,在begin
期间复制它,然后在apply
期间设置它。
至于推迟 PrimeFaces validation.js
和 beanvalidation.js
文件,这需要 <h:head>
的自定义渲染器,因为 PrimeFaces 实际上对它们进行了硬编码,而不是将它们声明为 @ResourceDependency
.您可以在 wiki of CombinedResourceHandler
.
中找到具体示例
package com.example;
import java.io.IOException;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
@ResourceDependencies({
@ResourceDependency(library="primefaces-aristo", name="theme.css"),
@ResourceDependency(library="primefaces", name="primefaces.js"), // Only necessary when at least one validation JS files needs to be included.
@ResourceDependency(library="primefaces", name="validation/validation.js"), // Only necessary when you need <p:clientValidator>.
@ResourceDependency(library="primefaces", name="validation/beanvalidation.js") // Only necessary when you use JSR303 bean validation.
})
public class HeadRenderer extends Renderer {
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
context.getResponseWriter().startElement("head", component);
}
@Override
public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
// NOOP.
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
for (UIComponent resource : context.getViewRoot().getComponentResources(context, "head")) {
resource.encodeAll(context);
}
context.getResponseWriter().endElement("head");
}
}
要获取到运行,请在faces-config.xml
中按如下方式注册:
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.Head</renderer-type>
<renderer-class>com.example.HeadRenderer</renderer-class>
</renderer>
</render-kit>
我正在尝试使用 OmniFaces 来推迟 PrimeFaces 脚本,如 answer.
中所示但是 PrimeFaces 在 head 中渲染了一个内联脚本,就像这样(我对脚本进行了美化和评论):
<script type="text/javascript">
if(window.PrimeFaces) {
// this line is always rendered in Development mode.
PrimeFaces.settings.projectStage='Development';
// these lines are added if Client Side Validation is enabled.
PrimeFaces.settings.locale='pt_BR';
PrimeFaces.settings.validateEmptyFields=true;
PrimeFaces.settings.considerEmptyStringNull=true;
}
</script>
当我 运行 应用程序时,出现一些 JS 错误(文件和错误):
validation.js.xhtml?ln=primefaces&v=5.3:1
Uncaught TypeError: Cannot read property 'en_US' of undefined
beanvalidation.js.xhtml?ln=primefaces&v=5.3:1
Uncaught TypeError: Cannot read property 'en_US' of undefined
produto.xhtml:2
Uncaught TypeError: Cannot set property 'locale' of undefined
如果我把一些变量放在 primefaces.deferred.js
中,像这样:
if (!primeFacesLoaded) {
window.PrimeFaces = {
// variables added - begin
settings: {
projectStage: 'Development',
locale: 'pt_BR',
validateEmptyFields: true,
considerEmptyStringNull: true
},
// variables added - end
ab: function () {
defer("ab", arguments);
},
cw: function () {
defer("cw", arguments);
},
focus: function () {
defer("focus", arguments);
}
};
}
前两个错误仍然出现,但第三个错误消失了。
显然,PrimeFaces JS 对象缺少以下属性:
locales: {
// other values...
en_US: {
// other values...
}
},
util: {
// other values...
},
所以,问题是:如何正确延迟这些 PrimeFaces 脚本属性?
P.S:版本:PrimeFaces 5.3、OmniFaces 2.3、Payara Server (Glassfish) 4.1.1.161
PrimeFaces.settings
是在 the answer 发布后引入的。同时更新了答案以考虑到这一点。更新后的脚本是:
DeferredPrimeFaces = function() {
var deferredPrimeFaces = {};
var calls = [];
var settings = {};
var primeFacesLoaded = !!window.PrimeFaces;
function defer(name, args) {
calls.push({ name: name, args: args });
}
deferredPrimeFaces.begin = function() {
if (!primeFacesLoaded) {
settings = window.PrimeFaces.settings;
delete window.PrimeFaces;
}
};
deferredPrimeFaces.apply = function() {
if (window.PrimeFaces) {
for (var i = 0; i < calls.length; i++) {
window.PrimeFaces[calls[i].name].apply(window.PrimeFaces, calls[i].args);
}
window.PrimeFaces.settings = settings;
}
delete window.DeferredPrimeFaces;
};
if (!primeFacesLoaded) {
window.PrimeFaces = {
ab: function() { defer("ab", arguments); },
cw: function() { defer("cw", arguments); },
focus: function() { defer("focus", arguments); },
settings: {}
};
}
return deferredPrimeFaces;
}();
基本上,只需将属性准备为一个空对象,在begin
期间复制它,然后在apply
期间设置它。
至于推迟 PrimeFaces validation.js
和 beanvalidation.js
文件,这需要 <h:head>
的自定义渲染器,因为 PrimeFaces 实际上对它们进行了硬编码,而不是将它们声明为 @ResourceDependency
.您可以在 wiki of CombinedResourceHandler
.
package com.example;
import java.io.IOException;
import javax.faces.application.ResourceDependencies;
import javax.faces.application.ResourceDependency;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.render.Renderer;
@ResourceDependencies({
@ResourceDependency(library="primefaces-aristo", name="theme.css"),
@ResourceDependency(library="primefaces", name="primefaces.js"), // Only necessary when at least one validation JS files needs to be included.
@ResourceDependency(library="primefaces", name="validation/validation.js"), // Only necessary when you need <p:clientValidator>.
@ResourceDependency(library="primefaces", name="validation/beanvalidation.js") // Only necessary when you use JSR303 bean validation.
})
public class HeadRenderer extends Renderer {
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
context.getResponseWriter().startElement("head", component);
}
@Override
public void encodeChildren(FacesContext context, UIComponent component) throws IOException {
// NOOP.
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
for (UIComponent resource : context.getViewRoot().getComponentResources(context, "head")) {
resource.encodeAll(context);
}
context.getResponseWriter().endElement("head");
}
}
要获取到运行,请在faces-config.xml
中按如下方式注册:
<render-kit>
<renderer>
<component-family>javax.faces.Output</component-family>
<renderer-type>javax.faces.Head</renderer-type>
<renderer-class>com.example.HeadRenderer</renderer-class>
</renderer>
</render-kit>