Grails - 在单个表单中创建多个嵌套对象

时间:2012-10-24 09:38:24

标签: grails

我只是层次结构。

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";

因此。我的问题是 - 如何以单一形式创建多个嵌套对象?

1 个答案:

答案 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=""/>