0

ajax 呼び出しから作成された製品のリストを取得しました。このリストには、製品の名前と製品番号が表示されます。ここで、製品リストのリスト要素をクリックして、製品をフォームに追加したいと考えています。

私はSpring MVCを使用しているため、フォームはフォームからのデータを入力する必要があるバッキングオブジェクトを使用しています。追加したい製品は、バッキング オブジェクトのリストに含まれている必要があります。

フォームでは、合計金額も計算したいと思います。そのため、製品リストにあるよりも多くの情報が必要です。

バックエンドに json として投稿するのではなく、@ModelAttribute を使用するだけです。

リスト内でフォームをクリックしたときに、どうにかして完全なオブジェクト (製品) をフォームに与えることは可能でしょうか?

うまくいけば、私は自分自身を十分に説明しました。

ソースコードは次のとおりです。

$(document).ready(function() {
    $.getJSON('/oms/ajax/products', function(data) {  
        $.each(data, function(key, obj) {
            $('#productList').append('<li onclick=\"addProduct(' + obj.productName + ')\">' + obj.productName + '</li>');
        });
    });
});

function addProduct(name) {
    $('#orderItems').append('<li><input type=\"text\" name=\"order.lineItems[i]\" value=\"' + name + '\" /></li>');
}

public class OrderDTO {
    private List<OrderItemDTO> lineItems;
    /** getters and setters **/
}

public class OrderItemDTO {

    private String productCode;
    private String productName;
    private String description;
    private Float price;
    private Integer quantity;
    /** getters and setters **/
}
4

1 に答える 1

0

あなたがする必要があるのは、非表示の入力フィールドとして項目を追加および削除して、フォームの DOM をいじることです。

Spring MVC は、添字によってアイテムの Collection を処理します。これは、リストとマップの両方で同じように機能します。リストの場合:

<form:form modelAttribute="myModel">
   <form:hidden path="myListItems[0].name" />
   <form:hidden path="myListItems[1].name" />

   <form:hidden path="myMapItems['key1'].name" />
   <form:hidden path="myMapItems['someOtherKey'].name" />
</form:form>

これは、2 つのアイテムをリストに追加する、または 2 つのアイテムをマップに追加する通常の方法を示しています。これは、Spring JSTL タグを使用してフォームを構築します。ただし、これを動的に行う必要があるため、代わりに次のようなものを追加します。

これは、Spring が上記の 2 番目のリスト項目を生成する方法です。それを機能させるための鍵は、名前属性を正しく取得することです。基本的に、すべての Spring JSTL タグは何らかのフォーム入力を生成します。動作させるための最良の方法は、JSTL タグを使用してどのように動作するかを確認し、結果の HTML タグを単純に複製することです。

入力を正しく取得する方法を理解したら、JavaScript を記述して正しい入力をフォームに動的に追加するだけです。jQueryを使用しているように見えるので、次のようなことができます:

var myModel= $('#myModel);
$("<input />",{
  type: 'hidden',
  id: 'myListItems1.name',
  name: 'myListItems[1].name',
  value: 'someValue'
}).appendTo(myModel);

ここで、 #myModel はフォーム用に生成された ID です。入力要素を作成し、それをフォームに追加するだけです。十分に単純です。

ただし、ここで問題が発生します。Spring MVC は、単純なセッターを使用して、モデル属性の値を取得/設定します。これは、リスト/マップで値を簡単に取得および設定できることを意味しますが、モデル属性がセッションにある場合、Spring MVC は既にそこにある項目を削除しないことも意味します。これが意味することは、次の例で説明できます。

ユーザーが注文に 3 つのアイテムを追加してプレビューしたとします。コントローラーへの往復を行うと、Model Atttribute のコレクションに 3 つのアイテムが作成されます (リストと番号が連続している場合は、インデックス 0、1、および 2 の要素)。ここで、ユーザーが項目 2 (インデックス 1) が必要ないと判断し、それを削除したとします。したがって、当然、JavaScript はフォームからその項目を削除します。ただし、ユーザーが送信すると、フォームにインデックス 1 の項目が含まれていなくても、モデル属性のコレクションに残ります。これは、Spring MVC がフォーム送信から渡されたもののみを設定するためです。設定されていないものは追跡しません。

したがって、削除のためにあなたがしなければならないことは、どういうわけかそれらを追跡することです. 私がこれを達成した方法は2つあります。1 つ目は、コレクション内のオブジェクトに削除フラグを追加することです。フラグは単純なブール値で、true の場合、コントローラー/サービス レイヤーはこのアイテムが削除されたことを認識し、無視します。JavaScript でこれを実装する方法は、アイテムを削除するときに、削除フラグの別の非表示の入力を置き換える/追加して、それを「true」に設定するだけです。

2 番目のオプションは、すべての正当なアイテムが 1-N になるように、削除時にすべてのアイテムをシフトアップすることです。フォームの送信時に、モデル属性とともに「有効な」カウントを送信します (個別の RequestParam またはモデル属性の値として直接)​​。コントローラー/サービス層は、リストにいくつ含まれるべきかを認識し、属していないものを取り除くことができます。

これらすべてをうまく機能させることは、どの方法をとっても挑戦であり、Spring がどのように機能するかをしっかりと理解する必要があります。いくつかの簡単なテスト アプリを作成し、Spring が (特にビューで) 生成するものを確認し、それについて理解することを強くお勧めします。

これらすべてをどのように実装するかについては、どのようにコーディングするかによって完全に異なります。ビューに保持するデータの量を制限しようとする傾向があるため、私のアプローチは、注文でアイテム番号と数量のリストのみを送信することです。これは注文システムにとって特に重要だと思います。なぜなら、人々はあなたの JavaScript を操作することができ、悪意のある人がショッピング カート内の商品の価格を変更して、最終的にあなたをだますからです。ブラウザが送信するものを決して信用しないでください。

于 2013-03-25T12:00:25.160 に答える