【问题标题】:How to re-execute scripts in re-rendered regions?如何在重新渲染的区域重新执行脚本?
【发布时间】:2013-03-15 10:39:00
【问题描述】:

我使用richfaces / ajax4jsf 部分地重新渲染我的页面区域,这是一个精简的示例:

<a4j:commandButton value="..." reRender="infoBlock" action="#{...}"/>
<h:panelGrid id="infoBlock">
  <h:outputText value="..."/>
  <f:verbatim>
    <script type="text/javascript">
      console.log('test')
    </script>
  </f:verbatim>
</h:panelGrid>

我的问题是,重新渲染 infoBlock 时脚本 console.log('test') 不会重新执行。

顺便说一句,我知道我可以删除脚本标签并在上面的示例中使用oncomplete="console.log('test')"。然而,在实际应用程序中,脚本由我使用的组件渲染更复杂,因此更改它可能非常棘手。

所以我的问题是:如何在重新渲染的区域中重新执行脚本?

【问题讨论】:

    标签: javascript richfaces ajax4jsf


    【解决方案1】:

    您提供的代码示例完全符合您的要求。每次单击按钮时 - test 文本都会写入控制台。这是 RichFaces 中的开箱即用行为 - 重新渲染区域中的脚本被重新评估。

    【讨论】:

    • 我又试了一次,没有控制台日志,甚至警报都不起作用。但我使用的是旧版本的 Ajax4jsf:1.0.6。也许这就是问题所在?他们是否在新版本/丰富的面孔中改变了这一点?
    【解决方案2】:

    脚本应该是静态的,它们操作的数据应该是动态的,所以不要尝试这样做。相反,当重新渲染区域时,执行一些回调,对一些更改的动态数据进行操作。你已经有了一个机制:oncomplete="rerendered('infoBlock')"

    然后,您将在某处使用静态代码来读取动态数据并对其进行处理 - 静态代码不应嵌入页面上的脚本元素中:

    function rerendered(regionName) {
       //Do something depending on regionName
    }
    

    至于为什么它不能按原样工作,我们需要再“低”一点。

    一个给定的脚本元素对象有一个标志,表明内容是否已经被执行,当一个脚本元素被插入到主 DOM 树中时,它只有在标志为false 时才会被执行。

    使用.innerHTML等时,html里面的脚本元素根本不会执行。

    似乎上述两种机制都在使用中。

    【讨论】:

    • 我明白你的意思,但是脚本标签是由我使用的组件呈现的,并且将代码移动到 oncomplete 事件可能非常棘手。其次,脚本标签的内容会发生变化,因为它们取决于支持 bean 的属性。
    • @TimBüthe 对不起,但我认为你没有明白 - 将代码移动到静态 JS 文件。如果它需要动态生成,那么您将静态代码与动态数据混合在一起,这就是我所说的不好。 oncomplete 属性中需要的只是一个函数调用,就像我展示的那样,它永远不会被修改。示例:您动态生成类似console.log("test") 的内容。只有字符串"test" 是动态数据,而console.log 是静态代码。它们可以而且应该分开。
    • 这是不可能的,或者至少需要做很多工作。我使用Apache MyFaces 和使用的组件inputCalendar 呈现HTML 以及包含20 行动态JavaScript 的脚本标记。要改变这一点,我将不得不重写整个组件。所以我想我正在寻找某种解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多