我只是层次结构。
class Atom { String value}
class Unit {
List atoms
static hasMany = [ atoms:Atom ]
String name
}
class Block {
List unitss
static hasMany = [ units:Unit ]
String name
}
假设我想创建一个包含两个单元的块,每个单元有两个原子。 所以,首先,我创建了四个原子形式的原子。然后,我创建两个单位,并选择以前创建的原子。最后,我创建了块并选择了以前创建的单元。这不方便,所以我想以单一形式移动所有创建逻辑。我使用了本文中的方法http://www.2paths.com/2009/10/01/one-to-many-relationships-in-grails-forms/
简而言之,我在Block类中添加了方法:
def getExpandableUnitList() {
return LazyList.decorate(units,FactoryUtils.instantiateFactory(Unit.class))
}
另外,我添加了调用js函数的按钮:
var unitCount = ${blockInstance?.units.size()} + 0;
function addUnit()
{
var htmlId = "unit" + unitCount;
var deleteIcon = "${resource(dir:'images/skin', file:'database_delete.png')}";
var templateHtml = "<div id='" + htmlId + "' name='" + htmlId + "'>\n";
templateHtml += "Unit "+ (unitCount + 1) + "\n";
templateHtml += "<input type='hidden' id='expandableUnitList[" + unitCount + "].name' name='expandableUnitList[" + unitCount + "].name' />\n";
templateHtml += "<span onClick='$(\"#" + htmlId + "\").remove();'><img src='" + deleteIcon + "' /></span>\n";
templateHtml += "</div>\n";
$("#UnitList").append(templateHtml);
unitCount++;
}
现在,我可以在一个表单中创建包含单位的块(请参阅下图,抱歉表单设计不好)
Form 1 http://imageshack.us/a/img833/8775/screenshotfrom201210241.png
然而,这种形式也不方便 - 我们不能将原子添加到单位。
所以,我将lazylist添加到单元类中,并添加了另一个具有几乎相同js代码的按钮。 现在,我有了这个:
Form 2 http://imageshack.us/a/img31/8775/screenshotfrom201210241.png
但是,当我创建这个表单时 - 它不会保存我的原子。这是预期的行为,因为我们单位的懒惰列表不知道atom的惰性列表。而且我不知道如何管理它。我尝试的唯一的东西 - 下面的代码,但它不起作用。
templateHtml += "<input type='hidden' id='expandableBlockList[" + blockId + "].add(expandableUnitList[" + unitCount + "].name)' name='expandableBlockList[0].add(expandableUnitList[" + unitCount + "].name)' />\n";
因此。我的问题是 - 如何以单一形式创建多个嵌套对象?
答案 0 :(得分:1)
查看Grails文档 - 特别是关于Gorm cascading behavior的部分,它解释了您要查找的内容。
...无论是一对一,一对多还是多对多,定义belongsTo都会导致更新从拥有类级联到其依赖(关系的另一面),对于许多/一对一和一对多的关系,删除也会级联。
如果你没有定义belongsTo,那么就不会发生级联,你必须手动保存每个对象(除了一对多的情况,在这种情况下保存如果新实例在hasMany集合中,则会自动级联。
编辑:
BTW - 不确定这是否是拼写错误,但您的Block定义不包含任何单位
我很快就提交了一个答案,可能应该多考虑一下 - 听起来你的问题更多的是表单方面与域名定义。目前,当您的域名已定义时,应能够在创建单元时创建Atom及其与Unit的关系。这是一个非常简单的表格,用于说明在如何定义输入方面需要做些什么。
<form ...
Unit: <input type="text" name="name" value="" />
Atom 1: <input type="text" name="atoms[0].value" value="" />
Atom 2: <input type="text" name="atoms[1].value" value="" />
...
</form>
原子集合的大小在这里是硬编码的示例,但在更具伸缩性的解决方案中,您可以动态定义它们。因此,在提交时,这将创建单元,它是2原子。
编辑: 你尝试过这样的事情:
Block: <g:textField name="name" value=""/>
<br />
Unit 1: <g:textField name="units[0].name" value=""/> atoms:
<g:textField name="units[0].atoms[0].value" value=""/>
<g:textField name="units[0].atoms[1].value" value=""/>
<br />
Unit 2: <g:textField name="units[0].name" value=""/> atoms:
<g:textField name="units[0].atoms[0].value" value=""/>
<g:textField name="units[0].atoms[1].value" value=""/>