Сохранение идентификаторов разметки уникальными для элементов панели - PullRequest
0 голосов
/ 21 декабря 2011

У меня есть панель, которую я использую для отображения информации о местоположении.У меня есть страница, которую я использую для отображения информации о назначении доставки, которая включает два местоположения.Страница «Моя доставка» дважды включает панель «Расположение» - один раз для источника и один раз для пункта назначения.Этот пример был упрощен, поэтому у Location есть только одно свойство Name.

Вопрос:

Как лучше всего установить идентификатор разметки для имени (и другие свойства) обоих местоположений, сохраняя их уникальность?


Пример кода

LocationPanel.java

public class LocationPanel extends BasePanel {

    public LocationPanel(String id, String locCode) {
        super(id);
        init(locCode);
    }

    private void init(String locCode) {
        LocationInfo locModel = new LocationInfo(locCode + " Location");
        CompoundPropertyModel model = new CompoundPropertyModel(locModel);
        Label name = new Label("name");
        setDefaultModel(model);
        add(name);
    }
}

LocationPanel.html

<html xmlns:wicket="http://wicket.apache.org">
<body>
    <wicket:panel>
        <h3><span wicket:id="name">SAMPLE location</span></h3>
    </wicket:panel>
</body>
</html>

SetDeliveryAppointment.java

public class SetDeliveryAppointment extends BaseWebPage{

    public SetDeliveryAppointment(String id) {
        super(id);
        init();
    }

    private void init() {
        Panel origin = new RampLocationInformationPanel("origin", "LAX");
        Panel dest = new RampLocationInformationPanel("dest", "DAL");
        WebMarkupContainer delivery = new WebMarkupContainer("delivery");
        delivery.add(origin);
        delivery.add(dest);
        add(delivery);
    }
}

SetDeliveryAppointment.html

<html xmlns:wicket="http://wicket.apache.org">
<body>
<wicket:extend>
    <wicket:container wicket:id="delivery">
        <div wicket:id="origin"></div>
        <div wicket:id="dest"></div>
    </wicket:container>
</wicket:extend>
</body>
</html>

Цель:

Итак, что я хотел бы видеть в результирующем HTML, так это:

Окончательный вариант просмотра исходного кода HTML Цель

<html>
<body>
    <div id="origin">
        <!-- The exact id doesn't matter -->
        <!-- as long as 'origin' and 'name' are contained in it -->
        <h3><span id="origin_name">LAX location</span></h3>
    </div>
    <div id="dest">
        <h3><span id="dest_name">DAL location</span></h3>
    </div>
</body>
</html>

Бонус: Это действительно сквозная проблема.В идеале нам бы хотелось, чтобы каждый компонент Wicket получал уникальный идентификатор, но мы хотим, чтобы он был предсказуемым на основе предписанных нами правил.Идеальное решение могло бы решить эту проблему.

Отказ от ответственности: я новичок в Wicket, поэтому будьте спокойны, если это глупый вопрос

Ответы [ 4 ]

2 голосов
/ 21 декабря 2011

Когда вы используете JS, вы не должны использовать #id (например, как в jQuery использовать относительные селекторы) или генерировать фрагмент кода javascript, в который вы передадите component.getMarkupId().

Не уверен насчет селена, возможно, лучше использовать каркас для тестирования калитки (он достаточно мощный).

0 голосов
/ 22 декабря 2011

Это всегда компромисс между использованием HTML class и использованием HTML id. При разработке компонента Wicket, компонент должен иметь конечную цель повторного использования, не так ли? Мое личное предпочтение - придерживаться class, особенно, если повторно использовать компоненты на той же странице. Затем вы полагаетесь на их иерархию (будучи настолько неспецифичной, насколько это возможно) с интеграцией JS, стилем CSS и тестами Selenium.

0 голосов
/ 21 декабря 2011

Итак, вот один способ, которым это может быть достигнуто.Если модель на родительском элементе компонента instanceof CompoundPropertyModel, то идентификатор этого родительского компонента можно использовать для изменения идентификатора разметки дочернего элемента.

public class ComponentMarkupListener implements IComponentOnBeforeRenderListener {
  public void onBeforeRender(Component component) {
    if (component instanceof WebMarkupContainer || component instanceof Label) {
        component.setOutputMarkupId(true);

        if((component.getParent().getDefaultModel()) instanceof CompoundPropertyModel ){
          component.setMarkupId(component.getParent().getId()
              +"_"+ component.getId() + "_ID");
        }else{
          component.setMarkupId(component.getId() + "_ID");
        }
    }
  }
}
0 голосов
/ 21 декабря 2011

Вы можете просто вызывать setMarkupId("origin"); и setMarkupId("destination"); (я не помню, если setOutputMarkupId(); является обязательным, чтобы заставить его работать, хотя) на каждом экземпляре вашей панели. Имейте в виду, что вам нужно позаботиться об уникальности идентификаторов на странице (но Wicket не будет генерировать имена, конфликтующие с ни «origin», ни «destination»).

Редактировать: объясните немного больше, как это сделать, я бы написал LocationPanel.java так:

public class LocationPanel extends BasePanel {

   public LocationPanel(String id, String locCode) {
    super(id);
    //sets the markupId to the wicket:id passed
    //you'll have to make sure you don't have the same wicket:id in the whole hierarchy
    //of your page though 
    setMarkupId(id);
    setOutputMarkupId(true);
    init(locCode);
   }

   private void init(String locCode) {
    LocationInfo locModel = new LocationInfo(locCode + " Location");
    CompoundPropertyModel model = new CompoundPropertyModel(locModel);
    Label name = new Label("name");
    setDefaultModel(model);
    add(name);
  }
}
...