如何从Wicket导航DOM

如何从Wicket导航DOM,wicket,Wicket,我想知道是否有可能在Java代码中修改wicket组件父级的HTML代码来修改其属性,而不使其成为wicket中的组件。例如,我想从Java向li标记添加active <li> <a wicket:id="home" href="#"> <i class="icon-home"></i> <span>Home</span> </a> <

我想知道是否有可能在Java代码中修改wicket组件父级的HTML代码来修改其属性,而不使其成为wicket中的组件。例如,我想从Java向li标记添加active

<li>
   <a wicket:id="home" href="#">
     <i class="icon-home"></i>
     <span>Home</span>
   </a>                     
</li>

  • 比如说,在代码中添加一个属性而不将其作为组件引用到父级中。

    我认为这是不可能的,这完全违背了Wicket的模块化特性。(更不用说页面实际上是作为流呈现的,没有构建DOM树。)

    Wicket中的组件不应该依赖于它们之外的内容。如果要更改活动/非活动控件的逻辑,该怎么办?或者,在更可能的情况下,您只想更改标记。或者,如果您只想在没有任何周围标记的情况下对组件进行单元测试

    Wicket的设计是为了避免这些“远距离的恐怖行为”,以创建真正可自行测试的组件


    您需要一个封装整个列表的组件,它可以跟踪哪些项处于活动状态(通过其模型)。乍一看,这似乎需要做很多工作,但当你看到结果时,你会意识到理解正在发生的事情是多么容易。

    你可以使用javascript来完成。在本例中,我覆盖了链接的renderHead(),但也可以通过一个行为来完成

    public class TestPage extends WebPage {
    
        public TestPage(final PageParameters parameters) {
            super(parameters);
    
            add(new AjaxLink<Void>("link") {
                boolean active = false;
                @Override
                public void onClick(AjaxRequestTarget target) {
                    active = !active;
                    target.add(this);
                }
                @Override
                public void renderHead(IHeaderResponse response) {
                    super.renderHead(response);
                    String addOrRemove = (active) ? ".addClass('active')" : ".removeClass('active')";
                    response.render(OnDomReadyHeaderItem.forScript("$('#" + getMarkupId() + "').parent('li')" + addOrRemove + ";"));
                }
            });
        }
    }
    
    
    <!DOCTYPE html>
    <html xmlns:wicket="http://wicket.apache.org">
    <head>
    <style type="text/css">
      li.active {background-color: red;}
    </style>
    </head>
    <body>
      <ul>
        <li><a wicket:id="link">TOGGLE</a></li>
      </ul>
    </body>
    </html>
    
    公共类测试页扩展网页{
    公共测试页(最终页参数){
    超级(参数);
    添加(新AjaxLink(“链接”){
    布尔活动=假;
    @凌驾
    公共void onClick(AjaxRequestTarget目标){
    活动=!活动;
    目标。添加(此);
    }
    @凌驾
    公共无效renderHead(IHeaderResponse响应){
    super.renderHead(响应);
    字符串addOrRemove=(活动)?“.addClass('active'):”.removeClass('active')”;
    response.render(OnDomReadyHeaderItem.forScript($('#“+getMarkupId()+”).parent('li')“+addOrRemove+”));
    }
    });
    }
    }
    li.active{背景色:红色;}
    
    • 拨动

    是的,它会将代码与标记耦合,但这并不总是一个问题。如果你觉得你正在复制和粘贴这个代码一遍一遍,考虑创建一个合适的组件:

    谢谢你的评论。我更希望wicket允许我在Java代码中获取父标记容器,而不是添加AttributeModifier。理论上,您可以尝试通过标记流对其进行操作,但如果可能的话,可能会非常复杂。只需添加容器:)感谢分享您在这方面的立场,我认为构建DOM树是可能的。但是,我相信如果wicket在呈现页面之前必须跟踪所有HTML标记,内存占用会更大。只是要明确,这不是我的立场,这是wicket设计的目的。你要么遵循Wicket的哲学,要么如果你不喜欢它,就选择一个不同的框架,但试图将一些陌生的东西塞进一个框架很少是一个好主意。如果您在解决方案投入使用之前就担心内存占用,那么这绝对不是一个好主意。