2

ここでの私の主な質問は、1つの動的フォーム内で1対多の関係を管理する場合のプラママップの処理と、動的フォームを介してドメインオブジェクトを編集/更新する場合の1対多の処理のベストプラクティスです。私の質問への入力は次のとおりです。

以下に示すドメインオブジェクトを1つの動的フォームで作成できるフォームをハックすることができました。電話番号を作成して連絡先に割り当てるための別のフォームを用意しても意味がないため、私のアプリケーションでは、すべてを1つのフォームで作成します。以前の質問で尋ねたものと同様の何かを実装することができました(助けてくれた人々に感謝します)

class Contact{

    String firstName
    String lastName
    // ....
    // some other properties
    // ...

    static hasMany = [phones:Phone]
    static mapping = {
        phones sort:"index", cascade: "all-delete-orphan"
    }
}

class Phone{
    int index
    String number
    String type
    Contact contact

    static belongsTo = [contact:Contact]
}

基本的に、「params」マップから値を取得して自分で解析し、ドメインオブジェクトと関連付けを手動で作成することができました。つまり、デフォルトのスキャフォールディングで使用されているのと同じロジックを使用しませんでした。

Contact c = new Contact(params)

など....、私はすべてのパラメータをループし、ドメインオブジェクトを手作りして保存しましたが、すべてうまくいきました。

私のコントローラーには、次のようなコードブロックがあります(これは、ポイントを示すために削除されています)

//create the contact by handpicking params values
def cntct = new Contact()
cntct.firstName = params.firstName
cntct.lastName = params.lastName
//etc...

//get array of values for number,type
def numbers = params['phone.number']
def types =  params['phone.type']

//loop through one of the arrays and create the phones
numbers.eachWithIndex(){ num, i ->
    //create the phone domain object from 
    def phone = new Phone()
    phone.number = num
    phone.type = types[i]
    phone.index = i
    cntct.addToPhones(phone)
}

//save

私の質問は次のとおりです。

  • このような状況に対処するためのベストプラクティスは、この場合はコマンドオブジェクトを使用すると機能します。はいの場合、これに関する詳細情報はどこにありますか。検索中に見つけたすべての例は、1対1の関係を扱っています。 1対多の例が見つかりませんでしたか?
  • この場合、連絡先オブジェクトを編集するときに電話を追加/削除するという観点から、電話の関係に対処するための最良の方法は何ですか。保存時に常に新しい電話を作成する必要があるため、作成ロジックは単純ですが、連絡先の更新を処理するときに、ユーザーが電話を削除したり、既存の電話を編集したり、新しい電話を追加したりした可能性があります。今のところ、連絡先が持っているすべての電話を削除し、フォームに投稿された内容に従って再作成するだけですが、それは最善の方法ではないと思います。また、既存の電話をループすることもないと思います。投稿された値と比較して手動の差分を実行することもそれを行うための最良の方法ですが、これに対処するためのベストプラクティスはありますか?

ありがとう、うまくいけば質問は明確です。

[編集]詳細については、フォーム内のjavascript(jquery)を使用して電話情報を動的に追加および削除できます[/ edit]

4

4 に答える 4

1

免責事項:grailsを使用するときに次のアプローチが機能するかどうかはわかりません。後で教えてください。

動的フォームのより良い方法を参照してください。著者は次のように述べています。

LineItems を追加するために、新しいインデックスを計算して DOM に追加する js がいくつかあります。LineItemを削除するとき、すべてのインデックスの番号を付け直す必要がありますが、これは避けたいことです

では私は何をすべきか

次のインデックスを格納する変数があります

var nextIndex = 0;

ページが読み込まれると、コレクションの子の数を計算する JavaScript 関数を実行し、nextIndex 変数を構成します。JQuery または YUI を使用できます。

子を静的に追加する

テンプレートを格納する変数を作成します (通知{index} )

var child   = "<div>"
           +=     "<div>"
           +=         "<label>Name</label>"
           +=         "<input type="text" name=\"childList[{index}].name\"/>"
           +=     "</div>"
           += "</div>"

ユーザーが [子を追加] ボタンをクリックすると、正規表現を使用して{index}を nextIndex 変数に格納されている値に置き換え、1 ずつ増やします。次に、DOMに追加します

Javascript を使用して動的に HTML 要素を追加および削除するも参照してください。

子を動的に追加する

ここでは、パオロ・ベルガンティーノのソリューションを見ることができます

取り除くことで

しかし、削除するときに問題が大きくなると思います。いくつの子を削除しても、nextIndex 変数には触れません。こちらをご覧ください

/**
  * var nextIndex = 3;
  */

<input type="text" name="childList[0].name"/>
<input type="text" name="childList[1].name"/> // It will be removed
<input type="text" name="childList[2].name"/>

childList 1を削除するとします。すべてのインデックスを再番号付けする必要がありますか???

サーバー側では、AutoPopulatingList を使用します。childList 1は削除されているため、AutoPopulatingListは null として処理します。だから私は初期化で

List<Child> childList = new AutoPopulatingList(new ElementFactory() {
   public Object createElement(int index) throws ElementInstantiationException {
       /**
         * remove any null value added
         */    
       childList.removeAll(Collections.singletonList(null));

       return new Child();
   }
});

このように、コレクションには 2 つの子 (null 値なし) のみが含まれ、クライアント側ですべてのインデックスの番号を付け直す必要はありません。

追加/削除については、洞察を得ることができるシナリオを示すこのリンクを見ることができます。

Grails UI プラグインも参照

于 2010-08-19T06:28:36.623 に答える
1

ありがとう、

あなたの答えは、より広い検索を行うための洞察をもたらし、実際に私の質問のすべての入力をカバーする素晴らしい投稿を見つけました. これは、これを読んでいる人のための参考資料です。私のケースをどのように実装したかについてのブログ エントリをすぐに書きますが、このリンクは ino の適切なソースと実際の例を提供するはずです。

http://www.2paths.com/2009/10/01/one-to-many-relationships-in-grails-forms/

于 2010-08-20T12:17:31.687 に答える