无法过滤 Wicket 中的下拉选项

Unable to filter a dropdownchoice in Wicket

我有一个对象 Users,它包含一组另一个对象 Roles。我创建了一个新面板 ListPanel,用于保存用户具有的角色的列表视图。所有这些都包含在一个数据表中。不过,我希望能够过滤该角色列表,这就是我被困的地方。当我尝试过滤 DataTable 上的角色时,出现以下错误:"Could not convert value: Admin to type: java.util.Set. Could not find compatible converter." Admin 是我从下拉列表中获得的值。

我不知道从这里去哪里。根据我的阅读,您不能将 Converter 与 DropDownChoice 一起使用,因此我研究了创建 Renderer 但传递到 Renderer 的值是一个 String 而不是 Role 对象。我认为渲染器是正确的选择,但需要在其他地方进行一些更改才能使其正常工作。

实体

public class User {
     private String id;
     private String name;
     private Set<Role> roles;
     ......properties/getters/setters.......
}

public class Role {
     private String role;
     private int active;
     ......properties/getters/setters.......
}

搜索面板

public class UserSearchPanel extends BreadCrumbPanel {
    private static final int ROWS_PER_PAGE = 20;

    @Inject
    private UserDao userDao;

    @Inject
    private RoleDao roleDao;    

    private final UserDataTable dataTable;

    public UserSearchPanel( final String id, final IBreadCrumbModel breadCrumbModel ) {
        super( id, breadCrumbModel );
        NotificationPanel feedback = new NotificationPanel( "feedback" );
        feedback.setOutputMarkupId( true );
        add( feedback );

        UserDataProvider dataProvider = new UserDataProvider( userDao );
        dataProvider.setFilterState( loadFilterState() );

        // create the form used to contain all filter components
        final FilterForm<User> form = new FilterForm<User>( "userSearchForm", dataProvider ) {

            @Override
            protected void onSubmit() {
                dataTable.setCurrentPage( 0 );
            }

        };

        dataTable = new UserDataTable( "dataTable", createColumns(), dataProvider, ROWS_PER_PAGE, this );

        dataTable.addTopToolbar( new FilterToolbar( dataTable, form, dataProvider ) );
        form.add( dataTable );
        add( form );
    }

    /**
     * The columns shown on the page.
     */
    private List<IColumn<User, String>> createColumns() {

        List<IColumn<User, String>> columns = new ArrayList<IColumn<User, String>>();
        List<String> choices = new ArrayList<String>();
        try {
            choices = roleDao.getAvailableRoles();
        } catch ( Exception e ) {
            e.printStackTrace();
        }

        if ( choices.size() > 1 ) {
            IModel<List<? extends String>> filterChoices = Model.ofList( choices );
            columns.add( createChoiceColumn( "datatable.roles.label", "roles", "roles", filterChoices ) );
        }
        return columns;
    }

    private ChoiceFilteredPropertyColumn<User, String, String> createChoiceColumn( final String key, final String sortProperty, final String propertyExpression, final IModel<List<? extends String>> filterChoices ) {

        IModel<String> label = getLabel();

        return new ChoiceFilteredPropertyColumn<User, String, String>( label, sortProperty, propertyExpression, filterChoices ) {

            @Override
            protected boolean enableAutoSubmit() {
                return false;
            }

            @Override
            public void populateItem( Item<ICellPopulator<User>> cellItem, String componentId, IModel<User> rowModel ) {
                cellItem.add( new ListPanel( componentId, rowModel ) );
            }
        };
    }

    private class ListPanel extends Panel {

        public ListPanel( String id, IModel<User> model ) {
            super( id );
            User user = (User) model.getObject();
            addList( user );
        }

        private void addList( User user ) {
            Set<Role> rolesSet = user.getRoles();
            List<Role> roles = new ArrayList<>();
            for ( Role role : rolesSet ) {
                roles.add( role );
            }

            ListView<Role> view = new ListView<Role>( "list", roles ) {
                @Override
                protected void populateItem( ListItem<Role> item ) {
                    final Role role = (Role) item.getModelObject();
                    item.add( new Label( "roles", role.getRole() ) );
                }
            };
            add( view );
        }
    }
}

我建议您创建一个 class,而不是使用您的 User 对象,它表示您要过滤的内容并对 IDataProvider 中的这些值做出反应。

当前发生的情况是您正在使用用户对象来表示您的 FilterState 并且 wicket 尝试将字符串 "ADMIN" 设置为 [=11= 的 Set<Role> ] 对象。

只需在单独的对象中声明不同的过滤器选项。

喜欢:

    class FilterState implements Serializable {
    private String roles;

    public String getRoles() {
        return roles;
    }

    public void setRoles(String roles) {
        this.roles = roles;
    }
}

class UserDataProvider implements IDataProvider<User>, IFilterStateLocator<FilterState> {

    private FilterState state;

    private UserDao userDao;

    public UserDataProvider() {
        state = new FilterState();
    }

    ....

    @Override
    public Iterator<? extends User> iterator(long first, long count) {
        //just some example filter logic, handled by the dao
        if (state == null || state.getRoles() == null) {
            return userDao.getUserList(first, count).iterator();
        } else {
            return userDao.getUserListByRoleName(state.getRoles(), first, count).iterator();
        }
    }

    @Override
    public FilterState getFilterState() {
        return state;
    }

    @Override
    public void setFilterState(FilterState state) {
        this.state = state;
    }

}