【问题标题】:Composite component jsf * primefaces复合组件 jsf * primefaces
【发布时间】:2014-01-17 09:35:07
【问题描述】:

我在使用 widgetVar 时遇到问题,而它的名称是动态生成的。我们如何正确地调用这样的小部件?组件代码:

<cc:attribute name="id" required="true" type="java.lang.String" />
...
<cc:implementation>
    <p:selectOneRadio widgetVar="widgetVariable#{cc.attrs.id}" id="#{cc.attrs.id}" required="false" immediate="#{cc.attrs.immediate}"
                      value="#{cc.attrs.value}">
        <p:ajax event="click" oncomplete="checkRadio()"/>
        <cc:insertChildren/>
    </p:selectOneRadio>

    <script type="text/javascript">
        /*  <![CDATA[ */

        function checkRadio() {
            var widgetVariable = widgetVariable#{cc.attrs.id}; //HERE PROBLEM
            widgetVariable.dosmth();
        }

        /*    ]]> */
    </script>
</cc:implementation>  

这就是它的工作原理,但是当我在页面上使用这个组件的许多实例时,widgetwar 有时会变得疯狂并为组件的许多实例制作 javascript。

编辑:一切正常。 无论如何,我有一个新问题。我在这个 .js 文件中创建了一些全局状态变量。

var state = -1;

function checkRadio() {
        var widgetVariable = widgetVariable#{cc.attrs.id}; //HERE PROBLEM
        widgetVariable.dosmth(state);
}

但是每个状态应该只针对一个复合实例,atm每个复合都使用这个var,有什么想法吗?

【问题讨论】:

  • id 的外观如何?它包含哪些字符?
  • 任何,一些字母/数字“myCompoennt”“something2”等
  • 所以没有特殊字符,只有字母数字字符?
  • 是的,我正在测试 atm Balus 解决方案,brb。

标签: javascript jsf primefaces composite-component


【解决方案1】:

实际上有两个问题。

第一个问题是您在 XHTML 文件而不是真正的 JS 文件中声明 JS 函数。如果您有多个这些组件,那么您基本上是在为 HTML 输出生成多个 JS 函数checkRadio()。在浏览器中拉出页面,右键单击并查看源代码。你基本上会看到

<script type="text/javascript">
    function checkRadio() {
        // ...
    }
</script>
<script type="text/javascript">
    function checkRadio() {
        // ...
    }
</script>
<script type="text/javascript">
    function checkRadio() {
        // ...
    }
</script>
...

在最后一个之前,它们会相互覆盖。所以当checkRadio() 被调用时,实际上最后一个会被调用。这显然是不对的。

你应该只有一个功能。您可以通过简单地将变量设置为函数参数来将其外部化。更重要的是,您不应该在 XHTML 文件中编写 JS 代码,而应在 &lt;h:outputScript&gt; 包含的独立 JS 文件中编写。额外的好处,即使你有多个复合组件,它也会自动确保只加载一个 JS 文件。

<cc:implementation>
    <h:outputScript name="myComposite.js" />
    ...
    <p:ajax event="click" oncomplete="checkRadio('#{cc.attrs.id}')" />
</cc:implementation>

回到你的具体问题,你的第二个问题,你可以利用window[variableName] 符号通过动态组合的变量名来掌握全局(窗口)变量。因此,myComposite.js 中的 checkRadio() 函数(随意命名,但与 myComposite.xhtml 相同的文件名将是最自我记录的)应该如下所示:

function checkRadio(compositeId) {
   var widgetVariableName = "widgetVariable" + compositeId;
   var widgetVariable = window[widgetVariableName];
   widgetVariable.dosmth();
}

【讨论】:

  • 我应该把这个js文件放在哪里?我添加了库标签 我将它放在复合组件所在的位置,但是当我要使用此复合组件进行页面时,它会在页面源中显示一些错误组件: ... ...
  • 与所有其他 JSF 资源相同的位置。在/resources 文件夹中。如果您希望它与复合 XHTML 位于同一文件夹中,只需根据实际的 /resources-relative 路径相应地更改 &lt;h:outputScript library&gt;。顺便说一句,“js”绝对是一个糟糕的库名称。另请参阅stackoverflow.com/questions/11988415/…
  • 只是将它作为另一个函数参数传递?
  • 每个复合组件可以有很多状态,我需要记住这些状态。例如,我得到了第 1 个状态 = 3 第 2 个状态 = 2 第 3 个状态 = 0 atm 这个 var 状态是全局的,它们都使用它。所以传递它不是一个解决方案,而这个 var 一次可以有 1 个状态
  • 我没有看到将它作为另一个函数参数传递是如何形成问题的。
猜你喜欢
相关资源
最近更新 更多
热门标签