Oracle ADF Найти в бине компонент с формы и принудительно обновить его


Лучше по возможности привязать компонент к бину с нужной областью памями (мы обычно используем pageFlowScope). А потом с помощью JSFUtils получать этот бин и рефрешить привязанный компонент.

Бины должны находиться в одном task flow.

MyBean myBean = (MyBean) JSFUtils.getManagedBeanValue("pageFlowScope.myBeanNameInXMLFILE");

RichRegion myRegion = myBean.getMyRegion();

UIUtils.updateUIComponent(myRegion);

Утилиты лежат в https://bitbucket.org/oracle-adf/adf-utils

Если не вариант, то можно делать способами описанными ниже.


Сейчас думаю, что по хорошему, компоненты можно находить относительно региона. После того как регион найден, можно на регионе выполнять метод findComponent(“”);


Найти в бине компонент с формы и принудительно обновить его


public void buttonClick(ValueChangeEvent valueChangeEvent) {
    UIUtils.printUIComponentInfo(valueChangeEvent);
}

Получаю идентификатор в консоли и работаю с ним.


Найти регион на котором располагается компонент


public void myMethod(ActionEvent actionEvent) {

    RichRegion region = (RichRegion)actionEvent.getComponent().findComponent("REGION_NAME);

    if(region != null){
        System.out.println("REFRESH REGION " + region.getId());
        region.refresh(FacesContext.getCurrentInstance());
    }  
}



Как делал раньше (Возможно, что есть еще что-то полезное для понимания)

В общем туева хуча всяких фрагментов, надо как-нибудь побыстрее найти компонент на форме.

Создаю SelectOneChoice на форме, ID которой хочу получить. autoSubmit=”true” valueChangeListener=”#{MyMethod.buttonClick}”

Обрабатываю событие.

public void buttonClick(ValueChangeEvent valueChangeEvent) {
    FacesContext contxt = FacesContext.getCurrentInstance();
    RichSelectOneChoice component = (RichSelectOneChoice)valueChangeEvent.getComponent();
    System.out.println("component " + component.getClientId(context));

Получаю:

****
pt1:supplier_fragment:0:pt1-suppliers:r1:1:pt1:soc1
****

Удаляю такие вещи как :0: :1: и убираю ненужный мне soc1


Возможно, что в свойствах компонента можно выставить “clientcomponent true” и в этом случае не нужно будет удялять руками нули и единицы.


Я разобрался, что всетаки за :0:, :1: и т.д. Они используются для идентификации компонента на странице, когда он располагается в каком-нибудь train. Если в пертов вагоне 0, если во 2, то 1 и т.д. При работе с компонентами программно, их всеравно приходится удалять.

Остается добавить id нужного компонента. И уже работать с ним.


Один элемент ну никах не хотел искаться:

UIComponent myComponent = UIUtils.findUIByAbsoluteID(CONSTANTS_UI.MY_REGION);
ComponentInfo.getUIComponentChildInfo(myComponent);

CONSTANTS_UI.MY_REGION = константа, опеределенная в бине. Т.е. строка в которой прописан путь до компонента.

Приходится по шагам искать нужный путь.


Вариант кратчайший:

Точно знаю, как найти элемент, задав путь до компоненента идентификатором вида: :pt1:region_1:pt1:region_2:gantt1

UIComponent myComponent = (UIComponent) FacesContext.getCurrentInstance().getViewRoot().findComponent(":pt1:region_1:pt1:region_2:gantt1");

Или сразу:

 UIProjectGantt ganttChart1 = (UIProjectGantt) FacesContext.getCurrentInstance().getViewRoot().findComponent(":pt1:region_1:pt1:region_2:gantt1");


Вариант подлинее:

FacesContext fctx =  FacesContext.getCurrentInstance();
UIComponent uic = fctx.getViewRoot().findComponent("pt1");
UIComponent uic1 = uic.findComponent("region_1");
UIComponent region = uic1.findComponent("pt1").findComponent("region_2");
UIProjectGantt ganttChart1 = (UIProjectGantt) region.findComponent("gantt1");


Пример пошагового поиска, который ранее использовал для поиска элемента формы в бине

В общем стандартными средствами (написанными ранее) ни в какую не хотел искаться элемент с формы.

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

private void updateFormProgrammaticallyWorks(){

    FacesContext fctx =  FacesContext.getCurrentInstance();
    UIComponent uic = fctx.getViewRoot().findComponent("pt1");

    System.out.println("------------------------------");

    UIComponent uic1 = uic.findComponent("tasks");
    UIComponent uic2 = uic1.findComponent("pt_tasks");
    UIComponent uic3 = uic2.findComponent("tasks_pgl");

    UIUtils.getUIComponentInfo(uic1);
    UIUtils.getUIComponentInfo(uic2);
    UIUtils.getUIComponentInfo(uic3);

    System.out.println("==============================");

    // Элемент с ныжным ID найден. В консоли написано, что попался
    // Присваиваем его переменной и принудительно обновляем.

    RichPanelGroupLayout pgl = (RichPanelGroupLayout)uic3.findComponent("tasks_pgl");
    AdfFacesContext.getCurrentInstance().addPartialTarget(pgl);        

}



public static void getUIComponentInfo(UIComponent uic) {

    try{

        System.out.println("=======================");
        System.out.println("||| " + uic.getId());
        System.out.println(uic.getRendererType());
        System.out.println(uic);

        System.out.println("----------");
        System.out.println("Children: " + uic.getChildCount());
        System.out.println(uic.getChildren());

        }  catch (Exception ex){
       System.out.println("Exception" + ex.toString());
    }

}


В общем смысл такой.
Берем постепенно с самого первого элемента главной формы идентификатор и считываем его в консоль.
Обычно по умолчанию что-то вроде d1.

Далее ищем идентификатор региона если он используется.
И уже дальше ищем идентификатор нужно элемента в нем.

Далее смотрим в консоли его потомка и вообще сколько этих потомков у него есть.
Подставляем потомка и смотрим потомка потомка. И так до того элемента, пока не найдется нужный.

Наверняка имеются и попроще решения.
Стандартным для меня способом, где в метод передаюется идентификатор элемент не находился.



Обновление элемента:

Привязываем в бине элемент, который нас интересует.

И достаточно выполнить всего 1 команду.

AdfFacesContext.getCurrentInstance().addPartialTarget(hierarchi);

В моем конкретном случае hierarchi - элемент типа UIHierarchyViewer. Т.е. по нажатию на кнопку перерисовывается вся иерархия.


Обновление:

private static final String PANEL_TEMPLATE = "pt1";

public void clickOnTasksPriorityHigh(ActionEvent actionEvent) {
    System.out.println("Button Pressed");

    UIComponent ui = FindUI.getUIComponent(PANEL_TEMPLATE);

    if (ui == null) {
        _logger.info("PanelTab component not found!");
        return;
    }
    if (!(ui instanceof RichPageTemplate)) {
        _logger.info("Component is not an af:panelTabbed");
        return;
    }

    _logger.info("ALL OK");



    RichPageTemplate rpt = (RichPageTemplate) ui;
    int childCount = rpt.getChildCount();
    List<UIComponent> children = rpt.getChildren();
    for (int ii = 0; ii < childCount; ii++) {
        UIComponent uiSDI = children.get(ii);
        _logger.info("Children: " + uiSDI.getChildren());
    }
}


public static UIComponent getUIComponent(String name) {
    FacesContext facesCtx = FacesContext.getCurrentInstance();
    return facesCtx.getViewRoot().findComponent(name);
}

Output:

INFO: ALL OK
INFO: Children: [RichGridRow[UIXFacesBeanImpl, id=gr1]]


Рекомендовали также посмотреть:
http://www.oracle.com/us/products/middleware/identity-management/58-optimizedadffacescomponentsearch-175858.pdf