【问题标题】:How to conditionally render plain HTML elements like <div>s?如何有条件地渲染纯 HTML 元素,如 <div>s?
【发布时间】:2023-03-11 20:54:01
【问题描述】:

我正在尝试实现一个复合组件,它可以以纯文本形式显示用户的信息详细信息,或者如果所需的详细信息是当前连接的用户的详细信息,则通过可编辑的输入文本字段显示它们。

我知道所有 UI 组件都可以通过 rendered 属性呈现,但是那些不是 UI 组件的呢(例如 div)

<div class = "userDetails" rendered = "#{cc.attrs.value.id != sessionController.authUser.id}">
    Name: #{cc.attrs.value.name}
    Details: #{cc.attrs.value.details}
</div>

<div class = "userDetails" rendered = "#{cc.attrs.value.id == sessionController.authUser.id}">
    <h:form>
        ...
    </h:form>
</div>

我知道 div 没有渲染属性,可能我根本没有找到正确的方法。我可以很容易地使用 JSTL 标记,但我想避免这种情况。

【问题讨论】:

    标签: html jsf-2 conditional-rendering


    【解决方案1】:

    表示 HTML &lt;div&gt; 元素的正确 JSF 组件是 &lt;h:panelGroup&gt;,其中 layout 属性设置为 block。所以,应该这样做:

    <h:panelGroup layout="block" ... rendered="#{someCondition}">
        ...
    </h:panelGroup>
    

    或者,将其包装在&lt;ui:fragment&gt;

    <ui:fragment rendered="#{someCondition}">
        <div>
            ...
        </div>
    </ui:fragment>
    

    或者当您已经使用 JSF 2.2+ 时,将其设为 passthrough element

    <div jsf:rendered="#{someCondition}">
    
    </div>
    

    请注意,当您想要对有条件渲染的组件进行 ajax 更新时,您应该改为对其父组件进行 ajax 更新。

    另见:

    【讨论】:

    • 谢谢!当谈到良好实践时,为所有这些小部件使用复合组件是否有意义?
    • 不客气。我个人会使用一个简单的包含文件。另见stackoverflow.com/questions/6822000/…
    【解决方案2】:

    从 JSF 2.2 开始,这很容易。通过使用 pass-through 元素,任何 HTML 元素都可以转换为具有 render 属性的 JSF 组件。

    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:jsf="http://xmlns.jcp.org/jsf">
        <div class="userDetails" jsf:rendered="#{cc.attrs.value.id != sessionController.authUser.id}">
            Name: #{cc.attrs.value.name}
            Details: #{cc.attrs.value.details}
        </div>
    </html>
    

    阅读更多https://jsflive.wordpress.com/2013/08/08/jsf22-html5/#elements

    【讨论】:

      【解决方案3】:

      我会用 &lt;h:panelGroup&gt; 包装你的 HTML

      <h:panelGroup rendered = "#{cc.attrs.value.id != sessionController.authUser.id}">
          <div class = "userDetails">
              Name: #{cc.attrs.value.name}
              Details: #{cc.attrs.value.details}
          </div>
      </h:panelGroup>
      
      <h:panelGroup  rendered = "#{cc.attrs.value.id == sessionController.authUser.id}">
          <div class = "userDetails">
              <h:form>
                 ...
              </h:form>
          </div>
      </h:panelGroup>
      

      如果您的项目中已有组件,则另一种选择是使用 Seam (&lt;s:div&gt;) 或 Tomahawk (&lt;t:htmlTag&gt;) 库中的组件。

      见:http://www.jsftoolbox.com/documentation/seam/09-TagReference/seam-div.html

      <s:div styleClass = "userDetails" rendered = "#{cc.attrs.value.id != sessionController.authUser.id}">
          Name: #{cc.attrs.value.name}
          Details: #{cc.attrs.value.details}
      </s:div>
      
      <s:div styleClass = "userDetails" rendered = "#{cc.attrs.value.id == sessionController.authUser.id}">
          <h:form>
              ...
          </h:form>
      </s:div>
      

      或者:http://myfaces.apache.org/tomahawk-project/tomahawk12/tagdoc/t_htmlTag.html

      <t:htmlTag value="div" styleClass = "userDetails" rendered = "#{cc.attrs.value.id != sessionController.authUser.id}">
          Name: #{cc.attrs.value.name}
          Details: #{cc.attrs.value.details}
      </t:htmlTag>
      
      <t:htmlTag value="div" styleClass = "userDetails" rendered = "#{cc.attrs.value.id == sessionController.authUser.id}">
          <h:form>
              ...
          </h:form>
      </t:htmlTag>
      

      【讨论】:

        【解决方案4】:

        您可以使用其他复合组件。没有 div 或其他附加标签,正是您需要的标签。看这个例子:

        <table>
            <tr>...</tr>
            <my:cc rendered="false">
                <tr>...</tr>
            </my:cc>
            <my:cc rendered="true">
                <tr>...</tr>
            </my:cc>
        </table>
        

        还有 my:cc 组件:

        <?xml version='1.0' encoding='UTF-8' ?>
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
        <html xmlns="http://www.w3.org/1999/xhtml"
              xmlns:cc="http://xmlns.jcp.org/jsf/composite">
        
            <cc:interface>
            </cc:interface>
        
            <cc:implementation>
                <cc:insertChildren />
            </cc:implementation>
        </html>
        

        使用 ajax 生成以下 HTML,根本不需要额外的标签。

        <table><tr>...</tr><tr>...</tr></table>
        

        【讨论】:

          猜你喜欢
          • 2017-12-10
          • 2021-05-01
          • 2011-09-08
          • 2023-03-22
          • 2022-01-22
          • 2020-03-01
          • 1970-01-01
          • 2022-01-11
          相关资源
          最近更新 更多