将 JavaScript 集成到 JSF 复合组件中,干净的方式

Posted

技术标签:

【中文标题】将 JavaScript 集成到 JSF 复合组件中,干净的方式【英文标题】:Integrate JavaScript in JSF composite component, the clean way 【发布时间】:2012-09-18 21:29:03 【问题描述】:

在 JSF 中,将 javascript 集成到复合组件中的“正确”和“干净”方式是什么?我是Unobtrusive JavaScript 的粉丝,并将 html 与 JS 与 CSS 分开。什么是尽可能少的怪癖的好方法?这是迄今为止我最喜欢的:

<composite:interface>
  // ...
</composite:interface>

<composite:implementation>
  // ...
  <script> initSomething('#cc.clientId'); </script>
</composite:implementation>    

我不喜欢的是,使用language A 生成language B。事件处理程序和其他东西基本上也是如此。我最喜欢的是通过&lt;insert favorite DOM JavaScript library here&gt; 附加这些处理程序。这可能吗?您如何进行这种集成?

【问题讨论】:

我不确定我是否理解您的具体问题/问题。例如,您可以使用 jQuery。 PrimeFaces 和 RichFaces 等流行的 JSF 组件库也使用 jQuery。 是的,当然。但不知何故,我必须检索对该 DOM 元素的引用。使用 ID 将是确保其唯一性的唯一方法(毕竟这就是 ID 的用途)。现在我不想生成一些 JavaScript,但是我如何获得一个 DOM 节点呢? 【参考方案1】:

我想说的是,只要您绝对肯定 HTML 元素的性质是如此独特,以至于您每次都绝对需要通过 ID 选择它,那么您所拥有的就是您能得到的最好的。

如果 HTML 表示不是唯一的(我可以想象 Facelets 模板或包含文件可能包含应用程序范围内的唯一 HTML 元素,如页眉、菜单、页脚等,而是一个复合组件哪个可以在一个视图中重复使用多次?我无法想象),那么您也可以考虑使用唯一的类名并对其进行挂钩初始化。

例如/resources/composites/yourComposite.xhtml

<cc:implementation>
    <h:outputScript library="composites" name="yourComposite.js" target="head" />
    <div id="#cc.clientId" class="your-composite">
        ...
    </div>
</cc:implementation>

/resources/composites/yourComposite.js 中加入(假设您使用的是 jQuery)

var $yourComposites = $(".your-composite");
// ...

如有必要,您可以在 jQuery.each() 中为每个元素提取自动生成的 HTML 元素 ID:

$yourComposites.each(function(index, yourComposite) 
    var id = yourComposite.id;
    // ...
);

【讨论】:

感谢您的意见。你是对的,大多数部分都不会是唯一的,即使它们是唯一的也没关系(即页眉、菜单、页脚)。但是当我通过 AJAX 重新加载或插入组件时,我的头痛开始了。我不能也不想重新初始化每个具有特定类名的组件。简单的替代方案是唯一的 id,或者设置一些标志来记住之前初始化的组件。后者需要一些代码,感觉很脏,不是很安全,并且增加了一些开销。您是如何解决此类问题的?

以上是关于将 JavaScript 集成到 JSF 复合组件中,干净的方式的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JSF 复合组件使页面上的 id 唯一?

如何在JSF中创建可重用的组件?

jsf 2.0 自定义组件/标签不复合

如何将验证器属性从 JSF2 复合组件传递给 h:inputText?

导致堆栈溢出异常的嵌套 JSF 复合组件

JSF ui:composition 和复合组件的问题