Как изменить компоненты в дереве? - PullRequest
0 голосов
/ 14 июля 2009

Из спецификации jsf 1.2 revB mrel2: низ страницы 65

■ Приложение должно иметь возможность программно изменять дерево компонентов в любое время в течение жизненного цикла обработки запросов (кроме случаев рендеринга представления), и система должна вести себя так, как ожидается. Например, должно быть разрешено следующее. Модификация представления во время рендеринга может привести к неопределенным результатам. Должна быть возможность разрешить удаление компонентов, добавленных системой шаблонов (таких как JSP), из дерева перед рендерингом. Должна быть возможность программно добавлять компоненты в дерево и отображать их в нужном месте иерархии. Должна быть возможность изменить порядок компонентов в дереве перед рендерингом. Эти манипуляции требуют, чтобы любые компоненты, добавленные в дерево, имели уникальные идентификаторы в области действия ближайшего родительского компонента NamingContainer. Значение свойства rendersChildren обрабатывается должным образом и может иметь значение true или false.

Так как же это сделать в adf 11g? Я пытаюсь реализовать систему авторизации для всего приложения, где компоненты видны / редактируются в зависимости от ролей пользователя. Однако я не могу найти способ подключиться к adf для изменения компонентов (например, RichInputText.setDisabled (true)) до того, как ответ будет записан. Я пробовал как с PhaseListener, так и с ViewHandlers. Кажется, ни один из них не позволяет мне выполнять вышеупомянутые функции. Так что же дает? Мне не повезло? Я что-то упустил?

Спасибо, Ben

public class AuthorizationPhaseListener implements PhaseListener {
  ...
  public PhaseId getPhaseId() {
    return PhaseId.RENDER_RESPONSE; // I've also tried in the other phases including ALL_PHASES
  }
  public void beforePhase(PhaseEvent p1) {
    // relevant ui components don't yet exist
    ...
  }
  public void afterPhase(PhaseEvent p1) {
    // relevant ui components exist, but have already been written to the stream, thus it's too late to modify them
    ...
  }
  ...
}

public class MyCustomViewHandler extends ViewHandlerWrapper {
  ...
  @Override
  public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException {
    AuthorizationService as = (AuthorizationService)RiscsContext.getCurrentInstance().getBean("AuthorizationService");
    // relevant ui components don't yet exist
    as.applyAuthorization();
    super.renderView(context, viewToRender);
    // relevant ui components exist, but have already been written to the stream, thus it's too late to modify them
    as.applyAuthorization();
  }
  ...
}

Ответы [ 3 ]

2 голосов
/ 07 декабря 2009

Вы действительно должны сделать это на стороне презентации. Не делайте это с помощью фазелистера, там это не для. Используйте атрибут rendered с умом. Вот несколько основных примеров того, как вы можете использовать это:

<h:someComponent rendered="#{bean.booleanValue}" />
<h:someComponent rendered="#{bean.intValue > 10}" />
<h:someComponent rendered="#{bean.objectValue == null}" />
<h:someComponent rendered="#{bean.stringValue != 'someValue'}" />
<h:someComponent rendered="#{!empty bean.collectionValue}" />
<h:someComponent rendered="#{!bean.booleanValue && bean.intValue != 0}" />
<h:someComponent rendered="#{bean.stringValue == 'oneValue' || bean.stringValue == 'anotherValue'}" />
0 голосов
/ 07 декабря 2009

Это позволяет получить доступ к / изменить компоненты пользовательского интерфейса в дереве, если это можно найти. Вы должны предоставить идентификатор клиентского компонента при использовании findComponent (). Единственная проблема остается в том, что он не дает вам доступ / контроль для загрузки начальной страницы (restore_view). :-( Для этого пока только 1 способ, которым я мог найти, который определяет EL в jspx / jsp / jsff.

0 голосов
/ 14 июля 2009

Согласно моему (ограниченному) поиску в документах, объект UIViewRoot является корневым узлом дерева представлений. Вы можете использовать его методы getChildren, чтобы найти соответствующие UIComponents и внести свои изменения. Однако я бы предложил другой путь.

Если вы предоставляете службу авторизации в качестве компонента, вы можете напрямую добавить методы в разметку. Например ...

public class User {
...
Map<String, Boolean> allowedRoles;
...
public Map<String, Boolean> getAllowedRoles { return allowedRoles; }
}

<h:inputText value="#{SomethingImportant}" disabled="!#{User.allowedRoles['importantRole']}/>

Еще лучше было бы использовать инфраструктуру безопасности, которая упростила бы это еще больше.

...