9

(对不起,如果这是一个菜鸟问题,我在grails 参考资料上找不到答案)

我有以下域层次结构:

用户>(有很多)调查>(有很多)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 = {
    }
}

当我创建调查时,我首先会看到这样的屏幕:

(民意调查)

我填写调查名称,然后单击添加调查问题,然后看到下一个屏幕:

(调查问题)

但它需要设置一个尚未完成的调查。

问题:我是否必须先创建并保存调查,然后对其进行编辑并添加调查问题(每个问题都需要单独创建和保存,然后才能创建响应),或者有没有办法像我一样添加子对象m 创建父对象?

我想使用动态脚手架,所以我不必手动创建控制器和视图。

问题和答案是完全独立的,不会在整个层次结构中重复使用。

4

4 回答 4

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

于 2012-09-03T11:22:17.903 回答
4

使用该用户界面,您应该创建、保存和添加。更好的方法是创建主/详细用户界面。你可以在这里看到这种方法:

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/

于 2012-08-30T15:37:33.023 回答
2

如果您在类中声明questions为 a ,那么您的视图将能够通过索引访问它们。ListSurvey

List questions
static hasMany = [questions: SurveyQuestion]

在您的 GSP 表格中,您可以使用如下内容:

<g:textField
    name="questions[0].question"
    value="${surveyInstance?.questions?.size() > 0 ? surveyInstance?.questions[0]?.question : ''}"/>

该值的三元值有点粗略,但可以很容易地隐藏在您自己的标签中。

如果您确实需要使用动态脚手架,您可以覆盖单个视图或用于生成视图的模板。或者,您可以使用字段插件来呈现questions属性的输入。

我创建了一个简单的应用程序,此时一切似乎都可以正常工作。我原以为必须编写一个PropertyEditor实现来增加列表,但似乎 Grails 2.1 会为你做这件事。

重新排序或删除问题需要更多的实验,但更新问题是可行的,即更改问题文本而不是SurveyQuestion创建新实例。

于 2012-09-05T14:53:23.267 回答
0

如果您要重复使用这些问题...也许您不应该使用 belongsTo =[survey:Survey]

然后,如果您没有这种关系,您可以创建一个用于创建问题的模板,并将它们添加到调查对象中的问题集合中,然后再保存!

于 2012-08-30T15:42:40.897 回答