Добавление дочерних элементов в объект домена до создания объекта домена
(Извините, если это нубский вопрос, я не смог найти ответы на ссылку в Grails)
У меня есть следующая heirarchy домена:
Пользователь > (имеет много) Survey > (имеет много) SurveyQuestion > (имеет много) SurveyQuestionResponse
Это два из вышеперечисленных:
class Survey {
String surveyName
static hasMany = [questions: SurveyQuestion]
static belongsTo = [user:User]
static constraints = {
}
}
class SurveyQuestion {
String question
static hasMany = [responses : SurveyQuestionResponse]
static belongsTo = [survey:Survey]
static constraints = {
}
}
Когда я создаю опрос, я сначала вижу такой экран:
Я заполняю название опроса, затем нажимаю добавить вопрос опроса и вижу следующий экран:
Но это требует проведения опроса, который еще не завершен.
Вопрос: Нужно ли сначала создавать и сохранять опрос, затем редактировать его и добавлять вопросы опроса (каждый из которых необходимо создать и сохранить по отдельности, прежде чем я смогу создавать ответы), или есть способ добавить дочерние объекты, как я? создание родительских объектов?
Я хочу использовать динамические леса, поэтому мне не нужно создавать контроллеры и представления вручную.
Вопросы и ответы полностью независимы и не будут повторно использоваться в иерархии.
4 ответа
Вы должны использовать командные объекты. Таким образом, вы можете удобно добавлять дочерние элементы при создании родительского элемента. Например
class CreateSurveyCommand {
String surveyName
List<SurveyQuestion> surveyQuestions =
org.apache.commons.collections.list.LazyList.decorate(
new ArrayList(),
new org.apache.commons.collections.functors.InstantiateFactory(SurveyQuestion.class))
}
По мнению (при условии index.gsp
) у вас есть что-то вроде:
<g:textField name="surveyName" value="${cmd?.question}" />
<g:each in="${cmd.surveyQuestions}" var="surveyQuestion" status="i">
<g:textField
name="surveyQuestions[i].question"
value="${cmd?.surveyQuestions[i].question}" />
</g:each>
<g:actionSubmit action="addQuestion"/>
Имея addQuestion
действие в вашем контроллере:
def addAction(CreateSurveyCommand cmd) {
cmd.surveyQuestions.add(new SurveyQuestion())
render(view:"index", model: [cmd: cmd])
}
Редактирование это еще одна тема, но работает так же.
Посмотрите на это сообщение в блоге:
http://blog.andresteingress.com/2012/06/29/groovy-2-0-love-for-grails-command-objects
Используя этот пользовательский интерфейс, вы должны создавать, сохранять и добавлять. Лучшим подходом является создание пользовательского интерфейса master / detail. Вы можете увидеть этот подход здесь:
https://github.com/leadVisionary/Grails-Survey-Module
http://programmingitch.blogspot.com/2009/10/data-binding-for-one-to-many.html
http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/
http://java.dzone.com/articles/creating-master-detail-forms
http://kapilpandit.wordpress.com/2009/02/25/complex_form_grails/
Если вы объявите questions
как List
в Survey
класс, то ваши взгляды смогут получить к ним доступ по индексу.
List questions
static hasMany = [questions: SurveyQuestion]
В вашей форме GSP вы можете использовать что-то вроде этого:
<g:textField
name="questions[0].question"
value="${surveyInstance?.questions?.size() > 0 ? surveyInstance?.questions[0]?.question : ''}"/>
Тройка для значения немного грубовата, но может быть легко спрятана в вашем собственном теге.
Если вам действительно нужно использовать динамические леса, вы можете переопределить отдельные представления или шаблоны, используемые для создания представления. В качестве альтернативы вы можете использовать плагин fields для визуализации входных данных для questions
имущество.
Я создал простое приложение, и в этот момент все, кажется, просто работает. Я ожидал, чтобы написать PropertyEditor
реализация, чтобы расширить список, но кажется, что Grails 2.1 сделает это за вас.
Изменение порядка или удаление вопросов потребует больше экспериментов, но обновление вопросов работает, то есть текст вопроса меняется, а не новый SurveyQuestion
экземпляр создается.
Если вы собираетесь повторно использовать вопросы... возможно, вам не следует использовать ownTo =[survey:Survey]
Затем, если у вас нет этой связи, вы можете создать шаблон для создания вопросов и добавить их в коллекцию вопросов в объекте опроса, прежде чем сохранять его!