如何多次包含相同的 JSF 复合组件以拥有自己的 javascript 范围?
How to make same JSF Composite Component included multiple times to have its own javascript scope?
我有一个像这样的 JSF 复合组件:
<cc:implementation>
<div id="#{cc.clientId}">
<h:outputScript library="js" name="helper.js"/>
<script type="text/javascript">
if(typeof variables === "undefined"){
var variables = {};
}
(function(){
variables.formid = '#{cc.clientId}';
})();
</script>
</div>
variables.formid
的值我在 helper.js
文件中使用。当我只包含这个复合组件一次时,它会正常工作。当我包含多个复合组件时,每个组件都会收到最后一个包含的复合组件的值,我该如何解决这个问题?
基本上有两种方法。
在helper.js
中添加一种"register"函数,这样你就可以在那里明确地注册它,而不是让它搜索复合材料。
<h:outputScript name="js/helper.js" target="head" />
<div id="#{cc.clientId}">
...
</div>
<h:outputScript>helper.register("#{cc.clientId}", { foo: "somevalue" });</h:outputScript>
可以通过 JS 对象作为参数提供选项。 a.o也是这样。 PrimeFaces 使用 PrimeFaces.cw()
函数,其中 "widget name" 也作为选项传递。
给合成一个独特的风格class像这样:
<h:outputScript name="js/helper.js" target="head" />
<div id="#{cc.clientId}" class="your-foo-composite">
...
</div>
这样 helper.js
就可以在文档准备期间通过 class 名称收集它们。
// Vanilla JS:
var yourFooComposites = document.getElementsByClassName("your-foo-composite");
// Or if you happen to use jQuery:
var $yourFooComposites = $(".your-foo-composite");
选项可以提供为 HTML5 data attributes (browser support is good these days)。
<div id="#{cc.clientId}" class="your-foo-composite" data-foo="somevalue">
可以通过以下方式获得:
// Vanilla JS:
for (var i = 0; i < yourFooComposites.length; i++) {
var yourFooComposite = yourFooComposites[i];
var clientId = yourFooComposite.id;
var dataFoo = yourFooComposite.dataset.foo;
// ...
}
// Or if you happen to use jQuery:
$yourFooComposites.each(function(index, yourFooComposite) {
var $yourFooComposite = $(yourFooComposite);
var clientId = $yourFooComposite.attr("id");
var dataFoo = $yourFooComposite.data("foo");
// ...
});
它还使您的 HTML 输出没有内联脚本。
与具体问题无关,在您的初始代码中使用 "js" 作为库名称并不好。仔细阅读 What is the JSF resource library for and how should it be used? 另请注意,我在 <h:outputScript>
中添加了 target="head"
属性。如果您正确使用 JSF <h:head>
组件,它会让 JSF 自动将脚本重新定位到生成的 HTML <head>
元素。
我有一个像这样的 JSF 复合组件:
<cc:implementation>
<div id="#{cc.clientId}">
<h:outputScript library="js" name="helper.js"/>
<script type="text/javascript">
if(typeof variables === "undefined"){
var variables = {};
}
(function(){
variables.formid = '#{cc.clientId}';
})();
</script>
</div>
variables.formid
的值我在 helper.js
文件中使用。当我只包含这个复合组件一次时,它会正常工作。当我包含多个复合组件时,每个组件都会收到最后一个包含的复合组件的值,我该如何解决这个问题?
基本上有两种方法。
在
helper.js
中添加一种"register"函数,这样你就可以在那里明确地注册它,而不是让它搜索复合材料。<h:outputScript name="js/helper.js" target="head" /> <div id="#{cc.clientId}"> ... </div> <h:outputScript>helper.register("#{cc.clientId}", { foo: "somevalue" });</h:outputScript>
可以通过 JS 对象作为参数提供选项。 a.o也是这样。 PrimeFaces 使用
PrimeFaces.cw()
函数,其中 "widget name" 也作为选项传递。给合成一个独特的风格class像这样:
<h:outputScript name="js/helper.js" target="head" /> <div id="#{cc.clientId}" class="your-foo-composite"> ... </div>
这样
helper.js
就可以在文档准备期间通过 class 名称收集它们。// Vanilla JS: var yourFooComposites = document.getElementsByClassName("your-foo-composite"); // Or if you happen to use jQuery: var $yourFooComposites = $(".your-foo-composite");
选项可以提供为 HTML5 data attributes (browser support is good these days)。
<div id="#{cc.clientId}" class="your-foo-composite" data-foo="somevalue">
可以通过以下方式获得:
// Vanilla JS: for (var i = 0; i < yourFooComposites.length; i++) { var yourFooComposite = yourFooComposites[i]; var clientId = yourFooComposite.id; var dataFoo = yourFooComposite.dataset.foo; // ... } // Or if you happen to use jQuery: $yourFooComposites.each(function(index, yourFooComposite) { var $yourFooComposite = $(yourFooComposite); var clientId = $yourFooComposite.attr("id"); var dataFoo = $yourFooComposite.data("foo"); // ... });
它还使您的 HTML 输出没有内联脚本。
与具体问题无关,在您的初始代码中使用 "js" 作为库名称并不好。仔细阅读 What is the JSF resource library for and how should it be used? 另请注意,我在 <h:outputScript>
中添加了 target="head"
属性。如果您正确使用 JSF <h:head>
组件,它会让 JSF 自动将脚本重新定位到生成的 HTML <head>
元素。