2015-07-18 4 views
4

У меня есть окно поиска, которое отображается на каждой странице. Код JSP для окна поиска вставляется на каждую страницу через плитки.Как использовать несколько форм/действий в одном представлении в Struts 2

Окно поиска имеет форму и класс действий SearchAction, которым необходимо предварительно загрузить некоторые свойства для выпадающих ящиков. Класс SearchAction имеет метод input(), который выполняет эту инициализацию.

Некоторые страницы также имеют свою собственную форму в основной области. Также с их собственным классом действий. Они также имеют метод input(), который выполняет некоторую предварительную загрузку.

  1. Возможно ли использовать два действия в одном и том же виде?
  2. Как каждая форма может иметь доступ к своим свойствам своих действий.
  3. И как мне удастся вызвать метод ввода обоих классов действий до отображения JSP?

Update:

Я добавляю обрезанную вниз пример, так как это, вероятно, не ясно, что я пытаюсь сделать. Это страница регистрации register.jsp с номером RegisterAction. И страница также содержит форму поиска. (BTW: Я ушел из геттер/сеттер и другие вещи в классах действий, чтобы держать его коротким):

register.jsp:

<s:form action="executeSearch"> 
    <s:textfield key="name" label="Name"/> 
    <s:textfield key="age" label="Age"/> 
    <s:submit/> 
</s:form> 

<s:form action="executeRegister"> 
    <s:textfield key="firstName" label="First Name"/> 
    <s:textfield key="lastName" label="Last Name"/> 
    <s:textfield key="age" label="Age"/> 
    <s:submit/> 
</s:form> 

struts.xml:

<action name="*Search" class="action.SearchAction" method="{1}"> 
    <result name="success">/searchresult.jsp</result> 
</action> 

<action name="*Register" class="action.RegisterAction" method="{1}"> 
    <result name="input">/register.jsp</result> 
    <result name="success">/registerOk.jsp</result> 
</action> 

SearchAction.java:

public class SearchAction extends ActionSupport { 

    private String name; 
    private int age; 

    @Override 
    public String input() throws Exception { 
     // preload the search form with some demo data 
     name = "test"; 
     age = 20; 
     return INPUT; 
    } 

    @Override 
    public String execute() throws Exception { 
     return SUCCESS; 
    } 

    ... 
} 

RegisterAction.java:

public class RegisterAction extends ActionSupport { 

    private String firstName; 
    private String lastName; 
    private int age; 

    @Override 
    public String input() throws Exception { 
     // preload the register form with some demo data 
     firstName = "John"; 
     lastName = "Rambo"; 
     age = 10; 
     return INPUT; 
    } 

    @Override 
    public String execute() throws Exception { 
     return SUCCESS; 
    } 

    ... 
} 

Допустим, я называю действие inputRegister.action. Затем вызывается RegisterAction.input(). Свойства заданы. И результат SUCCESS вызывает визуализацию register.jsp.

Но как насчет моей формы поиска. Как получить доступ к действию поиска и его модели. Разумеется, ни один из них не находится на ValueStack. И я также не вижу способ вызвать любые методы SearchAction, чтобы инициализировать его. Я намеренно выбираю age, чтобы быть в обоих классах действий. На отображаемой странице вы можете видеть, что форма поиска также обращается к RegisterAction -properties (потому что это находится поверх ValueStack). Но ему нужно получить доступ к SearchAction. Он должен показать 20, а не 10.

Rendered Jsp Page

Я явно делают это неправильно. Но даже после большого количества поисковых запросов я все еще не нашел правильного пути для этого.

+0

Не используйте 'input' для предварительной загрузки значений. Вы можете использовать 'готовый', если вам нужно. У вас может быть одно действие для перехода на страницу формы и другие для отправки из форм. –

ответ

1

Концепция представления используется для выполнения любого количества действий, и любое действие может иметь любое количество результатов. Результат возвращается для просмотра. Действие, которое возвращает представление, помещается поверх ValueStack, чтобы быть легко доступным путем оценки выражений OGNL. Результат результата может быть сопоставлен любому действию в любом классе действий. Он ничего не знает о действии, которое его вызывает, но оно может определить его, снова используя OGNL. Вы можете сопоставлять действия с разными методами одного и того же класса действий, поэтому вам не нужно много методов input().

EDIT:

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

<s:form action="executeSearch"> 
    <s:textfield key="searchBean.name" label="Name"/> 
    <s:textfield key="searchbean.age" label="Age"/> 
    <s:submit/> 
</s:form> 

<s:form action="executeRegister"> 
    <s:textfield key="firstName" label="First Name"/> 
    <s:textfield key="lastName" label="Last Name"/> 
    <s:textfield key="age" label="Age"/> 
    <s:submit/> 
</s:form> 

Примечание: атрибут key генерирует name, label и value.

Каждое действие должно инициализировать searchBean, если только оно не имеет области сеанса. Если вы поместите бит в сеанс, тогда вы должны использовать префикс #session.. Подробнее о OGNL вы можете найти на странице документов.

+0

Спасибо, Роман, за ваш ответ. Однако я все еще в темноте о том, как добиться этого. Нет проблем, если у меня есть одно действие. Я знаю, что действие может иметь много методов, которые я могу, например, сопоставить с несколькими кнопками отправки в форме. Но в моем случае у меня есть две совершенно разные формы, модели и их классы действий, которые выполняют инициализацию, проверку и т. Д. И мне нужно иметь обе страницы на одной странице. Я добавил пример, как я пытаюсь это сделать. Может быть, вы можете направить меня в правильном направлении? – nharrer

+0

В большинстве случаев Struts используется для подготовки стека значений, чтобы компоненты отображались в представлении, и каждый из них должен иметь уникальный путь OGNL для доступа к нему. –

+0

спасибо. Это привело меня в правильном направлении. Я записал свое решение в другом ответе. – nharrer

1

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

Это распространенная проблема, с которой легко обращаться с помощью Ajax, НЕ ЗАГРУЖАЙТЕ ВСЕ ВАШИ ПАРАМЕТРЫ. Пожалуйста, посмотрите на http://struts.jgeppert.com/struts2-jquery-showcase/index.action. Существует поле выбора выбора темы, которое было инициировано один раз. Загрузка другой части страницы выполняется через Ajax, и поэтому выбор темы, действие, которое инициирует поле выбора, не нужно повторно запускать. Вы можете легко использовать плагины struts 2 jquery для ее достижения.

Если вы не можете использовать Ajax (по какой-либо причине), тогда нет простого способа. Вы должны вручную инициировать элементы формы поиска в действии EACH, чтобы убедиться, что ваш тег struts может считывать данные, инициированные поисковой формой. Вы можете подумать об этом, как вам нужно, как, вырезать и вставить тело вашего действия поиска во все ваши действия!

0

Ok. Я отвечаю на свой вопрос. После многого другого времени Google я обнаружил, что инициализация вторичного действия с <s:action /> внутри JSP делает то, что мне нужно. Этот тег также может возвращать объект действия в переменную, которую мы можем нажать на ValueStack для формы. Пример выглядит так:

<!-- Initializes search model (preloading and stuff). --> 
<s:action var="searchAction" name="inputSearch" > 
    <s:param name="origin" value="inputRegister"/> 
</s:action> 

<!-- Pushing search action on ValueStack for the search form. --> 
<s:push value="#searchAction"> 
    <s:form action="executeSearch"> 
     <s:hidden name="origin"/> 
     <s:textfield key="name" label="Name"/> 
     <s:textfield key="age" label="Age"/> 
     <s:submit/> 
    </s:form> 
</s:push> 

<!-- This is the main form. It knows nothing about the search action. --> 
<s:form action="executeRegister"> 
    <s:textfield key="firstName" label="First Name"/> 
    <s:textfield key="lastName" label="Last Name"/> 
    <s:textfield key="age" label="Age"/> 
    <s:submit/> 
</s:form> 

Это работает хорошо. Однако есть два вопроса, которые необходимо учитывать:

  • Действие поиска используется на многих страницах. Если проверка формы поиска не удалась, нам нужно вернуться к исходной странице. Я решил это, указав параметр «origin». Это значение соответствует имени основного входа. Целевые действия поиска для этого действия, если проверка не выполняется.
  • Действие поиска инициализируется очень поздно, когда рендеринг JSP уже полностью продвинулся. Исключения на этом этапе могут быть проблематичными. Мне пришлось позаботиться, чтобы поймать все Исключения.
+0

Очень хакерское решение для очень простых требований. –

+0

Да. Я все еще изо всех сил пытаюсь найти хороший способ для этого. Я хочу, чтобы действия были полностью развязаны. Но все же нужно иметь их одинаковое мнение. Я открыт для лучших предложений. (Решение Alireza приятно, но, к сожалению, невозможно). – nharrer

+1

* Я хочу, чтобы действия были полностью развязаны * - Почему? У вас может быть одно действие, которое будет заполнять обе формы и отдельные действия для отправки из форм. –