0

我有一个简单的表单,它由使用 ListView 的表单中的可变数量的元素组成。每个元素都在一个表格行中,并包含一个名称(带有一个可以正常工作的链接)和一个 CheckBox,该复选框将该行标记为删除。只有复选框在表单中是可编辑的。表格底部是一个“删除选定”按钮,用于删除所有带有选定检查的条目。

我曾尝试使用 RepeatingView 和 ListView 执行此操作,但两者都有相同的问题 - 提交表单时复选框的内部模型状态未更新 - 它们总是错误的。在 SearchWrapper 类的 setSelected 方法中,永远不会显示记录器输出(其他记录是所以它不是记录问题)

谁能明白为什么这是错误的?

public class SavedSearchesTab extends Panel
{
  private static final Logger LOGGER = ...
  /**
   * 
   */
  public SavedSearchesTab( String p_id )
  {
    super( p_id );

    Form<?> l_form = new Form<Object>( "savedsearchform" ) {

      /**
       * @see org.apache.wicket.markup.html.form.Form#onSubmit()
       */
      protected void onSubmit()
      {
        LOGGER.info( "Form Submitted!" );
        for( String l_paramName : getRequest().getRequestParameters().getParameterNames() ) {
          LOGGER.info( "FormParam: " + l_paramName + ", value=" + getRequest().getRequestParameters().getParameterValue( l_paramName ) );
        }


        onDeleteSelected();
      }

    };
    l_form.setOutputMarkupId( true );
    add( l_form );


    List<UserSavedSearch> l_searches = getSearches();

    ListView<UserSavedSearch> l_repeater = new ListView<UserSavedSearch>( "repeater", l_searches ) {

      protected void populateItem( final ListItem<UserSavedSearch> p_item )
      {
        final UserSavedSearch l_search = p_item.getModelObject();
        SearchWrapper l_wrapper = new SearchWrapper( l_search );

        AjaxLink<UserSavedSearch> l_link = new AjaxLink<UserSavedSearch>( "searchnamelink" ) {

          private static final long serialVersionUID = 1L;

          public void onClick( AjaxRequestTarget p_target )
          {
            selectSearch( l_search );
          }
        };
        String l_linkText = l_search.getName();
        Label l_linkLabel = new Label( "searchnamelabel", l_linkText );
        l_link.add( l_linkLabel );

        p_item.add( l_link );

        TextArea<String> l_descriptionArea = new TextArea<String>( "searchsummary", new Model<String>( toSummary( l_search ) ) );
        p_item.add( l_descriptionArea );


        CheckBox l_checkbox = new CheckBox("searchcheckbox", new PropertyModel<Boolean>( l_wrapper, "selected" ) );
        p_item.add( l_checkbox );
      }
    };

    l_repeater.setReuseItems( true );
    l_form.add(l_repeater);
  }

  private List<UserSavedSearch> getSearches() {
    List<UserSavedSearch> l_searches = new ArrayList<UserSavedSearch>();
    // Make a couple of example ones for testing
    UserSavedSearch l_eg = new UserSavedSearch();
    l_eg.setName( "Example Search 1" );
    l_eg.setSearchArea( SearchArea.CUSTOMERS );
    l_searches.add( l_eg );
    l_eg = new UserSavedSearch();
    l_eg.setName( "Example Search 2" );
    l_eg.setSearchArea( SearchArea.CUSTOMERS );
    l_searches.add( l_eg );
    return l_searches;
  }

  private String toSummary( UserSavedSearch p_search ) {
    return "Summary of " + p_search.getName(); // TODO
  }

  protected void onDeleteSelected() {

  }

  protected void selectSearch( UserSavedSearch p_search ) {
    LOGGER.info( "Search " + p_search.getName() + " should be displayed!" );
  }  

  private class SearchWrapper implements Serializable {

    private static final long serialVersionUID = 1L;
    private UserSavedSearch m_data;
    private Boolean m_toDelete;

    public SearchWrapper( UserSavedSearch p_data ) {
      m_data = p_data;
      m_toDelete = false;
    }

    public boolean isSelected() {
      return m_toDelete;
    }

    public void setSelected( boolean p_selected ) {
     LOGGER.info( "SETTING SEARCHWRAPPER SELECTED STATE: " + p_selected );
      m_toDelete = p_selected;
    }

    public UserSavedSearch getSearch() {
      return m_data;
    }

  }

HTML:

<wicket:panel>
    <span class="sectiontitle"><wicket:message key="sectiontitle">savedsearches</wicket:message></span>

    <form wicket:id="savedsearchform">
        <fieldset>
            <table id="savedsearchtable">
                <tbody wicket:id="repeater">
                    <tr>
                        <td><input wicket:id="searchcheckbox" type="checkbox" name="searchselect" wicket:message="value:fragment.select.search" /></td>
                        <td><a href="#" wicket:id="searchnamelink"><span wicket:id="searchnamelabel">searchname</span></a></td>
                    </tr>
                    <tr>
                        <td colspan="2"><textarea wicket:id="searchsummary" readonly="readonly" rows="3" cols="100"/></td>
                    </tr>
                </tbody>
                <tr class="buttonPanel">
                    <td colspan="2">
                        <input type="submit" wicket:message="value:button.deleteselectedsearches"/>
                    </td>
                </tr>
            </table>
        </fieldset>
    </form> 
</wicket:panel>

提前致谢。

4

1 回答 1

0

问题是您在填充复选框时没有定义清晰的模型对象。该模型应该以您可以在 onSubmit 方法中进行初始化的方式进行初始化。

我建议在 SavedSearchesTab 构造函数中实例化您的模型对象,确保变量是最终的,将其添加到表单中并确保在所有层中都使用它。

关于您尝试恢复变量的方式,它不会那样工作,这不是 Wicket 应该如何工作的,如果您从我建议的地方实例化您的模型对象,您可以在 onSubmit 方法上访问该变量并且它将具有表单中的属性,您不必关心将表单值映射到您的 POJO,Wicket 使用模型为您执行此操作。

于 2013-07-19T15:02:42.783 回答