вызов компонента дочерней страницы из компонента родительской страницы в калитке - PullRequest
1 голос
/ 29 сентября 2011

У меня есть проблема, которую я пытался объяснить в изображении. Я надеюсь, что это поможет всем понять, что мне нужно.enter image description here

Моя базовая страница выглядит следующим образом (menuNavPanel - это панель дерева):

<div class="colContainer">
    <div class="leftColumn" >
        <div wicket:id="menuNavPanel"></div>
    </div>
    <div class="rightColumn">
        <wicket:child/>
    </div>
</div>

А Ny BIA Page, являющаяся дочерним элементом базовой страницы, выглядит следующим образом:

 <wicket:extend>
   <div wicket:id="bodyPanel"></div>
 </wicket:extend>

в моей панели дерева, когда я нажимаю на узел, код выглядит так:

    @Override
        protected void onNodeLinkClicked(AjaxRequestTarget target, TreeNode node) {
            super.onNodeLinkClicked(target, node);
            DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)node;
            Unit unitObject =(Unit) treeNode.getUserObject();

           // I want to call bodyPanel fo child page passing the  unitObject param


        }

Теперь, как я могу вызвать bodyPanel для дочерней страницы, передавая параметр unitObject из панели деревародительская страница?

Смогу ли я выразить свою проблему?Надеемся получить помощь:)

Ответы [ 5 ]

4 голосов
/ 29 сентября 2011

Вместо использования метода переопределения обновите до Wicket 1.5 и используйте новую шину событий для связи между вашими компонентами.Вы можете создать настраиваемое, безопасное для типов событие, специфичное для варианта использования вашего компонента: например, «ItemAddedToShoppingCart» или «GlobalThermoNuclearWarStarted».

Статья , связанная в руководстве по миграции 1.5 предоставляет достаточно информации о том, как настроить вещи.

3 голосов
/ 29 сентября 2011

Я не уверен, что правильно понял вопрос.Ваш BasePage определяет левый столбец с TreePanel и позволяет подклассам расширяться внутри правого столбца div.Обычно вы помещаете BodyPanel в подклассы BasePages.И теперь вы хотите вызвать метод BodyPanel для какого-либо события в TreePanel.

Вы можете сделать это с помощью переопределяемого метода на BasePage, который будет вызываться в TreePanel - getPage().Ваши дочерние страницы будут переопределять этот метод, и его реализация вызовет BodyPanel, который они содержат.

public class BasePage ... {
    // Hook 
    public void treePanelSelected(Object someObject) { }
    ...
}

public class ChildPage extends BasePage ... {

    BodyPanel bodyPanel;
    @Override
    public void treePanelSelected(Object someObject) { 
        bodyPanel.selectionChanged/(someObject);
    }
    ...
}


public class TreePanel ... { 

   ... 
    @Override
        protected void onNodeLinkClicked(AjaxRequestTarget target, TreeNode node) {
            super.onNodeLinkClicked(target, node);
            DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)node;
            Unit unitObject =(Unit) treeNode.getUserObject();

            ((BasePage)getPage()).treePanelSelected(unitObject);
        }
    }

Из-за моего незнания ваших конкретных потребностей и деталей реализации, я не понимаю, почемусоздание подкласса BasePage необходимо.Вы можете добавить BodyPanel прямо в BasePage и управлять им из того же класса.

2 голосов
/ 30 сентября 2011

Спасибо всем, просмотрев все приятные опции, я наконец выбрал путь для событийной шины, определенный martijn. То, что я сделал, я создал полезную нагрузку события и подключил панели для разговора. Мне также нужно было передать выбранный идентификатор / сущность на приемную панель.

Есть ли способ установить модель составного свойства приемной панели в соответствии с моделью элемента дерева, чтобы мне не нужно было делать модель вручную?

Пока мне это нравилось:

public class TreeNodeClickUpdate {

    private final AjaxRequestTarget target;

    private  final long selectedId;

    /**
     * Constructor
     *
     * @param target
     * @param selectedId
     */
    public TreeNodeClickUpdate(AjaxRequestTarget target, long selectedId)
    {
        this.target = target;
        this.selectedId = selectedId;
    }

    /** @return ajax request target */
    public AjaxRequestTarget getTarget()
    {
        return target;
    }

    public long getSelectedId() {
        return selectedId;
    }
 }

На стороне отправителя я сделал так:

  send(getPage(), Broadcast.BREADTH,
        new TreeNodeClickUpdate(target, unitObject.getId()));

И на приемном конце я получил это так:

           @Override
           public void onEvent(IEvent<?> event) {
              super.onEvent(event);

             if (event.getPayload() instanceof TreeNodeClickUpdate)
            {
              TreeNodeClickUpdate update = (TreeNodeClickUpdate)event.getPayload();
              setSelectedId(update.getSelectedId()); //sets to id field of panel
              update.getTarget().add(this);
            }


          }

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

  label = new Label("label",new PropertyModel<BiaHomePanel>(this,"selectedId"));

Позже, на самом деле, я хочу получить информацию от сущности и показать ее в форме. Есть ли хороший способ передать модели в лучшую сторону, или я должен передать в качестве параметра в полезной нагрузки события.

1 голос
/ 29 сентября 2011

Когда я столкнулся с проблемой, я подумал о двух способах решения этой проблемы (до 1.5):

a) реализовать вариант шаблона наблюдателя для уведомления других компонентов о событиях, как описано здесь: Реализация сложных межкомпонентных действий ajax в калитке - Способ наблюдения

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

Я решил пойти на вариант а) но это вводит связь между вашим компонентом и вашей реализацией страницы, что приводит к проблемам при самостоятельном тестировании панелей.Так что, может быть, б) может быть и лучшая идея, но поскольку мое приложение работает довольно гладко с реализованным а), и следующим большим шагом будет переключение на 1.5 и шину событий, я еще не пробовал б).

1 голос
/ 29 сентября 2011

Есть два способа сделать это.Один из них чище, но требует больше кода.Другой быстрый и грязный.

Метод 1: (Хорошо)

Поскольку ваша родительская страница расширяется, вы можете предоставить абстрактный метод в родительском, например

protected abstract WebMarkupContainer getBodyPanel();

, который реализован на вашей дочерней странице и возвращает соответствующую панель.Затем вы можете вызвать этот метод из панели на родительской странице.Это похоже на переопределяемый метод, предложенный другим пользователем.

Метод 2: (Плохо)

Иерархия компонентов калитки совместно используется родительской и дочерней страницами.Таким образом, если вы убедитесь, что ваш bodyPanel имеет уникальный wicketId и добавлен непосредственно в корень страницы, вы, вероятно, можете просто позвонить

get("bodyPanelId");

и он вернет соответствующую панель.

...