【问题标题】:<s:iterator not working properly for a list, i am using struts2<s:iterator 不能正常工作的列表,我正在使用 struts2
【发布时间】:2014-08-01 07:57:57
【问题描述】:

我有一个 s:iterator 正在迭代一个属性列表,对于列表中的每个项目都有属性键、值和类别。基于类别,我需要将值填充到迭代器内部定义的 div。我正在使用 jquery 选项卡。这里的迭代器没有正确迭代。请看代码很容易理解

<div id="tabs">
    <ul>
        <li><a href="#channel">Channel</a></li>
        <li><a href="#connection">Connection</a></li>                                        
    </ul>

    <s:iterator value="property" status="rowstatus">

        <div id="channel">
            <s:if test="(property[#rowstatus.index].category=='Channel')">
                <table>
                    <tr><s:hidden name="property[%{#rowstatus.index}].key" />
                        <td><s:label value="%{property[#rowstatus.index].key}">    </s:label></td>
                        <td> <s:textfield name="property[%{#rowstatus.index}].value">
                            </s:textfield>
                        </td>                                                      
                    </tr>
                </table>
            </s:if>

        </div>

        <div id="connection">

            <s:if test="(property[#rowstatus.index].category=='Connection')">
                <table>
                    <tr><s:hidden name="property[%{#rowstatus.index}].key" />
                        <td><s:label value="%{property[#rowstatus.index].key}"></s:label></td>
                        <td> <s:textfield name="property[%{#rowstatus.index}].value">
                            </s:textfield>
                        </td>                                                      
                    </tr>
                </table>
            </s:if>

        </div>

    </s:iterator>
</div>

【问题讨论】:

    标签: javascript jquery struts2 ognl valuestack


    【解决方案1】:

    更改 JSP

    <div id="tabs">
        <ul>
         <li><a href="#channel">Channel</a></li>
         <li><a href="#connection">Connection</a></li>                                        
        </ul>
        <div id="channel">
           <table>
                  <s:subset source="property" decider="channelDecider">
                    <s:iterator var="channel">
                      <tr><s:hidden name="property[%{property.indexOf(#channel)}].key" />
                        <td><s:label value="%{#channel.key}">    </s:label></td>
                        <td> <s:textfield name="property[%{property.indexOf(#channel)}].value" value="%{#channel.value}">
                            </s:textfield>
                        </td>                                                      
                      </tr>
                    </s:iterator>
                  </s:subset>
            </table>           
        </div>
    
        <div id="connection">
    
           <table>
                  <s:subset source="property" decider="connectionDecider">
                    <s:iterator var="connection">
                      <tr><s:hidden name="property[%{property.indexOf(#connection)}].key" />
                        <td><s:label value="%{#connection.key}">    </s:label></td>
                        <td> <s:textfield name="property[%{property.indexOf(#connection)}].value" value="%{#connection.value}">
                            </s:textfield>
                        </td>                                                      
                      </tr>
                    </s:iterator>
                  </s:subset>
            </table>           
        </div>
    </div>
    

    创建决策者

     public Decider getChannelDecider() {
     return new Decider() {
         public boolean decide(Object element) throws Exception {
             return ((MyElement)element).category.equals("Channel");
         }
     };
     }
    
     public Decider getConnectionDecider() {
     return new Decider() {
         public boolean decide(Object element) throws Exception {
             return ((MyElement)element).category.equals("Connection");
         }
     };
     }
    

    注意,MyElement 是具有相应属性的列表元素类型。

    【讨论】:

      【解决方案2】:

      迭代器工作正常。

      您正在为集合中的每个 item 创建一个 div,而不是为类似项目的每个 group 创建一个 div。

      虽然&lt;s:subset&gt; 会起作用,但作为替代方案,我会提出一个更简单、以 S2 为中心 的解决方案。

      附加MyElement代码:

      public class MyElement {
          public boolean isChannel()    { return category.equals("Channel");    }
          public boolean isConnection() { return category.equals("Connection"); }
      }
      

      我不喜欢使用字符串来表示类型。

      可以通过多种方式拆分列表;手动在动作中,简单快捷;通过实用程序类,如果您在多个地方需要此功能,那就太好了;等等

      一个可能的实用程序类:

      public class MyElementSplitter {
          // Also getters for both of these; possibly wrapped with an immutable collection.
          private List<MyElement> channels    = new ArrayList<>();
          private List<MyElement> connections = new ArrayList<>();
      
          public MyElementSplitter(List<MyElement> elements) {
              for (MyElement element: elements) {
                  if (element.isChannel()) {
                      channels.add(element);
                  } else if (element.isConnection()) {
                      connections.add(element);
                  }
              }
          }
      }
      

      注意:这可以显着增强,尤其是在您有其他类型的情况下。如果类型不是由字符串确定的,您可以通过使代码通用以公开其他类型来玩很多不错的游戏。

      在动作中,您对元素进行分类并将拆分器公开给视图:

      private MyElementSplitter elements; // And getter.
      
      public String execute() {
          // And any additional processing, list retrieval, etc.
          elements = new MyElementSplitter(allElements);
          return SUCCESS;
      }
      

      然后在视图中:

      <div id="channel">
          <s:iterator value="elements.channels" status="stat">
              <table>
                  <tr>
                      <s:hidden name="property[%{#stat.index}].key" />
                      <td><s:label value="%{property[#stat.index].key}" /></td>
                      <td><s:textfield name="property[%{#stat.index}].value" /></td>
                  </tr>
              </table>
          </s:iterator>
      </div>
      
      <div id="connection">
          <s:iterator value="elements.connections" status="stat">
              <table>
                  <tr>
                      <s:hidden name="property[%{#stat.index}].key" />
                      <td><s:label value="%{property[#stat.index].key}" /></td>
                      <td><s:textfield name="property[%{#stat.index}].value" /></td>
                  </tr>
              </table>
          </s:iterator>
      </div>
      

      如果这些部分总是相同的,那么我会将它们包装在基于 JSP 的自定义标记中。

      这将给我们留下以下内容:

      <div id="tabs">
          <ul>
              <li><a href="#channel">Channel</a></li>
              <li><a href="#connection">Connection</a></li>
          </ul>
      
          <app:elementTab id="channel"    values="elements.channels"    />
          <app:elementTab id="connection" values="elements.connections" />
      </div>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多