如何使用o:deferredScript延迟PrimeFaces.settings和客户端验证脚本 [英] How to defer PrimeFaces.settings and Client Side Validation scripts with o:deferredScript
问题描述
我正在尝试使用OmniFaces推迟PrimeFaces脚本,如本 answer 所示.
I'm trying to use OmniFaces to defer PrimeFaces scripts, as seen in this answer.
但是PrimeFaces会在头部渲染一个内联脚本,如下所示(我美化并评论了脚本):
But PrimeFaces render an inline script in head, like this (script beautified and commented by me):
<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错误(文件和错误):
When I run the application, I get some JS errors (file and error):
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 I put some variables in primefaces.deferred.js
, like this:
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);
}
};
}
第一个错误仍然发生,但是第三个错误消失了.
The two first errors still occur, but the third error go away.
显然,PrimeFaces JS对象缺少以下属性:
Apparently, the PrimeFaces JS object lacks the following properties:
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
P.S: Versions: PrimeFaces 5.3, OmniFaces 2.3, Payara Server (Glassfish) 4.1.1.161
推荐答案
The PrimeFaces.settings
was introduced after the answer was posted. The answer has in the meanwhile been updated to take that into account. The updated script is:
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
期间进行设置.
Basically, just prepare the property as an empty object, copy it during begin
and then set it during apply
.
关于推迟PrimeFaces validation.js
和beanvalidation.js
文件,这需要为<h:head>
自定义渲染器,因为PrimeFaces实际上是对它们进行硬编码而不是将它们声明为@ResourceDependency
.您可以在CombinedResourceHandler
的 Wiki上找到一个具体示例. .
As to deferring PrimeFaces validation.js
and beanvalidation.js
files, this requires a custom renderer for <h:head>
, as PrimeFaces one actually hardcodes them instead of declaring them as @ResourceDependency
. You can find a concrete example in 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
中进行如下注册:
To get it to run, register it as follows in 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>
这篇关于如何使用o:deferredScript延迟PrimeFaces.settings和客户端验证脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!