Grails 在创建域对象之前将子元素添加到域对象
(很抱歉,如果这是一个noob问题,我无法在上找到答案) 我拥有以下域继承权: 用户>(有很多)调查>(有很多)调查问题>(有很多)调查问题回答 这是上述两项:Grails 在创建域对象之前将子元素添加到域对象,grails,grails-2.1,Grails,Grails 2.1,(很抱歉,如果这是一个noob问题,我无法在上找到答案) 我拥有以下域继承权: 用户>(有很多)调查>(有很多)调查问题>(有很多)调查问题回答 这是上述两项: class Survey { String surveyName static hasMany = [questions: SurveyQuestion] static belongsTo = [user:User] static constraints = { } } class Surv
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 = {
}
}
创建调查时,我首先看到如下屏幕:
我填写调查名称,然后单击添加调查问题,然后查看下一个屏幕:
但这需要进行一次调查,调查尚未完成
问题:我是否必须先创建和保存调查,然后编辑调查并添加调查问题(在创建答复之前,每个问题都需要单独创建和保存),或者在创建父对象时是否有方法添加子对象
我想使用动态脚手架,这样我就不必手动创建控制器和视图
问题和答案完全独立,不会在整个层次结构中重复使用。使用该用户界面,您应该创建、保存和添加。更好的方法是创建主/详细用户界面。你可以在这里看到这种方法:
如果要重复使用这些问题。。。也许你不应该使用belongsTo=[调查:调查]
然后,如果没有此关系,则可以创建用于创建问题的模板,并在保存之前将其添加到调查对象中的问题集合中 您应该使用命令对象。这样,您可以在创建父元素时轻松地添加子元素。例如
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))
}
在控制器中执行addQuestion
操作:
def addAction(CreateSurveyCommand cmd) {
cmd.surveyQuestions.add(new SurveyQuestion())
render(view:"index", model: [cmd: cmd])
}
编辑是另一个主题,但工作方式相同
看看这篇博文:
如果您在
调查
类中将问题
声明为列表
,则您的视图将能够通过索引访问这些问题
List questions
static hasMany = [questions: SurveyQuestion]
在GSP表格中,您可以使用以下内容:
<g:textField
name="questions[0].question"
value="${surveyInstance?.questions?.size() > 0 ? surveyInstance?.questions[0]?.question : ''}"/>
值的三元组有点粗糙,但可以很容易地隐藏在您自己的标记中
如果确实需要使用动态支架,可以覆盖单个视图或用于生成视图的模板。或者,您可以使用呈现问题
属性的输入
我创建了一个简单的应用程序&在这一点上,一切似乎都正常工作。我本来希望必须编写一个PropertyEditor
实现来扩展列表,但Grails2.1似乎可以为您做到这一点
重新排序或删除问题需要更多的实验,但更新问题会起作用,即问题文本会发生更改,而不是创建新的
SurveyQuestion
实例。听起来像是,您希望保存调查。或者,您可以将所有这些设置为流,并删除编辑页面的“选择父项”部分。流对于多页创建过程很好。拜托,兄弟,你读过答案了吗?您应该使用命令对象和一个用LazyList装饰的集合,最好是javascript/jquery。你想要我的朋友做什么?你应该在配方中添加一个服务,以获得交易支持来澄清。我个人会像@crudolf建议的那样使用命令对象,或者全力以赴使用更丰富的前端,比如Angular,但如果你决定使用scaffolding,这可能会对你有用。这看起来是迄今为止最可行的选择,但它确实取决于使用静态scaffolding(或者至少自己实现某种形式的视图)。我问的原因是因为我更喜欢使用动态脚手架;更少的编码、更少的维护和更少的工作量;)(理论上,总有一个陷阱)
<g:textField
name="questions[0].question"
value="${surveyInstance?.questions?.size() > 0 ? surveyInstance?.questions[0]?.question : ''}"/>