【问题标题】:Wicket - ComponentNotFoundException: Component has been removed from pageWicket - ComponentNotFoundException:组件已从页面中删除
【发布时间】:2018-02-07 10:25:41
【问题描述】:

我正在使用 Wicket 7,但最近遇到以下异常:

org.apache.wicket.core.request.handler.ComponentNotFoundException:
Component 'navbar:navbarAvatar:navAvatarPanel:4:navAvatarArea:menuPanel:menuItem:menuLink' has been removed from page.

此错误来自我构建的顶部导航栏。导航栏有一个包含附加菜单链接 (menuLink) 的子菜单 (navAvatarPanel)。链接被添加到 ArrayList 并使用片段显示在 ListView 中。

这是我的代码:

NavBarPanel.java

public class NavBarPanel extends Panel {
    public NavBarPanel(String id) {
        super(id);
        /* ... */

        WebMarkupContainer navBarAvatar = new WebMarkupContainer(NavbarAvatar$wicketId) {
            private static final long serialVersionUID = -2447768280463773678L;

            @Override
            public boolean isVisible() {
                return session.isSignedIn();
            }
        };

        List<Panel> avatarMenuItems = new ArrayList<Panel>();
        avatarMenuItems.add(new MenuLink(Logout$wicketId, "Logout", WelcomeWebPage.class, menuModel));
        /* adding additional links at this point ... */

        navBarAvatar.add(new ListView<Panel>("navAvatarPanel", avatarMenuItems) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(ListItem<Panel> item) {
                final Panel panel = item.getModelObject();
                item.add(new MenuFragment(panel, "navAvatarArea"));
            }
        });

        this.add(navBarAvatar);
    }
}

public class MenuFragment extends Fragment {
    private static final long serialVersionUID = 5735397386662232792L;

    public MenuFragment(Panel panel, String area) {
        super(area, "menuFragment", NavBarPanel.this);

        add(panel);
    }
}

NavBarPanel.html

<wicket:panel>
    <!-- ... -->
    <div wicket:id="navbarAvatar" class="navbar-avatar">
        <ul>
            <wicket:container wicket:id="navAvatarPanel">
                <wicket:container wicket:id="navAvatarArea"/>
            </wicket:container>
        </ul>
    </div>
    <!-- ... -->
    <wicket:fragment wicket:id="menuFragment">
        <wicket:container wicket:id="menuPanel"></wicket:container>
    </wicket:fragment>
</wicket:panel>

MenuLink.java

public MenuLink(String markupId, String label, Class<? extends Page> page, MenuModel model) {
    super("menuPanel");
    this.markupId = markupId;
    this.page = page;
    this.model = model;
    this.initComponentTree(label);
}

private void initComponentTree(final String label) {
    WebMarkupContainer menuItem = new WebMarkupContainer("menuItem");

    Link<Void> menuLink = new Link<Void>("menuLink") {
        private static final long serialVersionUID = 1L;

        @Override
        public void onClick() {
            MenuLink.this.menuOnClick(label);
        }
    };

    menuLink.add(new Label("menuLabel", label));
    menuLink.setMarkupId(this.markupId);

    menuItem.add(menuLink);

    this.add(menuItem);
}

MenuLink.html

<wicket:panel>
    <li wicket:id="menuItem">
        <a wicket:id="menuLink">
            <span wicket:id="menuLabel">[label]</span>
        </a>
    </li>
</wicket:panel>

我不知道这个错误是从哪里来的。我也没有成功找到有关此异常的更多信息。

【问题讨论】:

    标签: java wicket wicket-7


    【解决方案1】:

    我的猜测是http会话已经过期,找不到菜单项,因为isVisible = session.isSignedIn();导致整个菜单不存在。

    如果是这种情况,那么应该改进 Wicket 以提供更好的异常消息,告知无法找到确切的组件,而不是请求的组件路径。

    附:建议使用onConfigure() {setVisible(...)} 而不是覆盖isVisible(),因为后者在渲染过程中会被调用多次,可能会更慢。

    【讨论】:

    • 如果是这样的话,通过替换'isVisible = session.isSignedIn();'来重现错误不是很容易吗用'isVisible = false;'甚至通过用'isVisible = true;'替换它来防止错误?但这在我的情况下不起作用/没有帮助。
    • 感谢 onConfigure 的推荐!
    • 你需要用菜单来渲染页面,然后你需要将你的代码更改为isVisible = false并且你需要在不重启应用程序的情况下更新字节码,然后点击一个菜单项,看看有什么发生。
    猜你喜欢
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2019-11-20
    • 2011-11-10
    相关资源
    最近更新 更多