Wicket Ajax错误日志:错误:无法绑定事件的监听器"单击"在元素" AjaxCheckBox"因为该元素不在DOM

时间:2015-09-16 06:57:38

标签: javascript ajax dom wicket wicket-6

嘿,当我运行程序时,我想动态地将面板添加到主页,然后使用" setVisible(boolean)"。 但不是我得到错误:
错误:无法绑定事件的监听器"单击" on element" institutCheck7"因为元素不在DOM 中 在Ajax调试器中。

我看到它与此处的可见性有关 post,但我没有得到我必须做的事情,它说,这在Wicket 7中得到了解决,但我仍然在运行6.20。

adminUIForm.add(myPanel= new MyPanel("myPanel", allThings));
    myPanel.setOutputMarkupId(true);
    myPanel.setVisible(false);
    //Note: Setting the OutputMarkupId allows actions such as setting components in/visible

    List<IColumn<ContactInfo, String>> columns = new ArrayList<IColumn<ContactInfo, String>>();
    columns = initializeColumns(columns);

    DataTable<ContactInfo, String> datatable = new DataTable<ContactInfo, String>("datatable", columns, provider, 10){
        private static final long serialVersionUID = 1L;

        @Override
        protected Item<ContactInfo> newRowItem(final String id, final int index,
                final IModel<ContactInfo> model) {
            Item<ContactInfo> rowItem = new Item<ContactInfo>(id, index, model);
            rowItem.add(new AjaxEventBehavior("onclick") {

                private static final long serialVersionUID = 1L;

                @Override
                protected void onEvent(AjaxRequestTarget target) {
                    System.out.println("click");
                    myPanel.setSelectedKontakt(model);
                    myPanel.setVisible(true);
                    target.add(myPanel);
                }
            });
            return rowItem;
        }
    };
    setTableProperties(datatable);
    adminUIForm.add(datatable);
}   

我重写newRowItem方法以添加onClick事件。我得到了#34;点击&#34;在我每次点击列时在控制台中,但是我收到此错误日志:

  

错误:Wicket.Ajax.Call.processComponent:尝试执行标记更新时找不到具有id [[institutTablePanel6]]的组件。确保在要尝试更新其标记的组件上调用component.setOutputMarkupId(true)。

     

错误:无法绑定事件的监听器&#34;单击&#34; on element&#34; institutCheck7&#34;因为元素不在DOM

中      

错误:无法绑定事件的监听器&#34;单击&#34;元素&#34; cont8&#34;因为元素不在DOM

中      

错误:无法绑定事件的监听器&#34;单击&#34; on element&#34; institutCheck9&#34;因为元素不在DOM

中      

错误:无法绑定事件的监听器&#34;单击&#34;元素&#34; conta&#34;因为元素不在DOM

中      

错误:无法绑定事件的监听器&#34;单击&#34; on element&#34; institutCheckb&#34;因为元素不在DOM

中      

错误:无法绑定事件的监听器&#34;单击&#34;元素&#34; contc&#34;因为元素不在DOM

中      

错误:无法绑定事件的监听器&#34;单击&#34; on element&#34; institutCheckd&#34;因为元素不在DOM

中      

错误:无法绑定事件的监听器&#34;单击&#34;关于元素&#34; conte&#34;因为元素不在DOM

这些错误都与&#34; myPanel&#34;中的组件绑定,我不知道如何解决这个问题。如果我之前将其设置为可见,我会遇到同样的问题,包括所有元素,这些元素将在工作流程中稍后隐藏。

编辑:

public class MyPanel extends Panel {
private static final long serialVersionUID = 1L;
private Form<Void> institutForm = new Form<Void>("institutForm");
private ListView<Institut> listView;
private IModel<ContactInfo> selectedKontakt;
private Set<Institut> allInstitut;

@Override
protected void onModelChanged() {
    //TODO maybe here
    super.onModelChanged();
}

public InstitutTablePanel(String id, final Set<Institut> allInstitut) {
    super(id);
    this.allInstitut = allInstitut;

    this.add(institutForm);

    List<Institut> allInstitutList = new ArrayList<Institut>(allInstitut);

    institutForm.add(listView = new ListView<Institut>("listView", allInstitutList) {

        private static final long serialVersionUID = 1L;

        protected void populateItem(final ListItem<Institut> item) {
            final IModel<Boolean> checked = Model.of(Boolean.FALSE);
            final IModel<String> expandState = Model.of("+");
            @SuppressWarnings("unused")
            final Label institutLabel;
            final Institut institut = item.getModelObject();
            // Define variables which concern only one item in populateItem

            final WebMarkupContainer div = createMarkUpContainer("cont");
            final WebMarkupContainer container = createMarkUpContainer("container");

            container.setEnabled(false);

            compareInstitute(checked, institut, container);
            item.add(container);

            div.add(new AjaxEventBehavior("onclick") {
                private static final long serialVersionUID = 1L;

                @Override
                protected void onEvent(AjaxRequestTarget target) {
                    expandOrCollapse(expandState, container);
                    target.add(institutForm);
                }
            });

            item.add(div);
            div.add(new AjaxCheckBox("institutCheck", checked) {
                private static final long serialVersionUID = 1L;

                @Override
                protected void onUpdate(AjaxRequestTarget target) {

                    //Not Important for this
                    target.add(institutForm);
                }
            });
            container.add(new ErhebungMatrixPanel("erhebungMatrix", institut, selectedKontakt));
            container.setVisible(false);
            div.add(institutLabel = new Label("institutLabel", new PropertyModel<Institut>(institut, "langName")));
        }
    });
    listView.setOutputMarkupId(true);
    listView.setReuseItems(true);
    institutForm.setOutputMarkupId(true);

}}

我编辑了我的setSelectedKontakt方法:

public void setSelectedKontakt(IModel<ContactInfo> model) {
    this.selectedKontakt = model;
    modelChanged();
}

在必要时触发更改。 问题是target.add(myPanel);不会再次触发populateItem。

2 个答案:

答案 0 :(得分:4)

错误消息说得非常清楚,看看DOM会告诉面板的标记不存在。多数民众赞成因为setVisible(false)甚至无法按预期使用CSS display: none;渲染组件。它不存在,所以事后不能修改它。但你可以告诉Wicket用setOutputMarkupPlaceholderTag(true)代替占位符。 Wicket然后创建一个不可见的标记,例如<span style="display: none;" id="mypanel1a"></span>,然后在将{vis}在true设置为NSCachedURLResponse时与真实组件交换。

答案 1 :(得分:1)

只是向那些确实会出现此错误的人提示:使用常见错误:

<wicket:container wicket:id="panel"/>

......而不是......

<div wicket:id="panel"/>

...放置面板的位置。方法调用setOutputMarkupId不会通知您它无法向wicket:container添加ID,因此您的target.add(panel)也会失败。