1

私は単に階層を持っています。

class Atom { String value}

class Unit { 
    List atoms
    static hasMany = [ atoms:Atom ] 
    String name
}

class Block {
    List unitss 
    static hasMany = [ units:Unit ] 
    String name
}

それぞれ2つの原子を持つ2つのユニットを含む1つのブロックを作成するとします。そこで、まず、原子の形で4つの原子を作成します。次に、2つのユニットを作成し、以前に作成した原子を選択します。最後に、ブロックを作成し、以前に作成したユニットを選択します。便利ではないので、すべての作成ロジックを1つの形式で移動したいと思います。この記事のアプローチを使用しました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++;
}

これで、1つのフォームのユニットでブロックを作成できます(下の画像を参照してください。フォームのデザインが悪いのでごめんなさい)

フォーム1http://imageshack.us/a/img833/8775/screenshotfrom201210241.png

ただし、この形式も便利ではありません。ユニットに原子を追加することはできません。

そこで、ユニットクラスにレイジーリストを追加し、ほぼ同じjsコードを持つ別のボタンを追加しました。今、私はこれを持っています:

フォーム2http://imageshack.us/a/img31/8775/screenshotfrom201210241.png

ただし、このフォームを作成すると、アトムは保存されません。私たちのユニットのレイジーリストはアトムのレイジーリストを知らないので、それは予想される振る舞いです。そして、私はそれを管理する方法がわかりません。私が試した唯一のこと-以下のコードですが、機能しません。

templateHtml += "<input type='hidden' id='expandableBlockList[" + blockId + "].add(expandableUnitList[" + unitCount + "].name)' name='expandableBlockList[0].add(expandableUnitList[" + unitCount + "].name)' />\n";

それで。私の質問は、単一のフォームで複数のネストされたオブジェクトを作成する方法ですか?

4

1 に答える 1

1

Grails のドキュメント (具体的には、Gorm cascading behaviorに関するセクション) を参照してください。探しているものが説明されています。

... 1 対 1、1 対多、または多対多のいずれであっても、 begsTo を定義すると、所有クラスからその従属クラス(関係の反対側)に更新がカスケードされます。多/1 対 1 および 1 対多の関係の削除もカスケードされます。

membersTo を定義しない場合、カスケードは発生せず、各オブジェクトを手動で保存する必要があります(1 対多の場合を除きます。この場合、新しいインスタンスが hasMany コレクションにある場合、保存は自動的にカスケードされます)。 .

編集:

ところで-これがタイプミスかどうかはわかりませんが、ブロック定義にユニットが含まれていません

私はすぐに回答を送信しましたが、おそらくもっと考えるべきだったでしょう。あなたの問題は、ドメイン定義よりもフォーム側にあるようです。現在、ドメインが定義されているため、ユニットを作成するときに、Atom とユニットとの関係を作成できるはずです。入力を定義する方法に関して何をする必要があるかを説明するための非常に単純なフォームを次に示します。

<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 Atoms になります。

編集:次のようなことを試しましたか:

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=""/>
于 2012-10-24T16:32:15.320 に答える