0

Spring AutoPopulatingList と JQuery を使用して動的フォームを作成しました。追加は魔法のように機能し、新しいアイテムが作成されてデータベースに保持されます。問題は削除にあります。ブラウザー側の要素の削除に関係なく、更新メソッドは常に完全なリストを取得します。

コントローラの更新方法は簡単です

@RequestMapping(value = "/user/{id}", method = RequestMethod.POST)
@ResponseBody
public String updateUser(@PathVariable("id") int id, @ModelAttribute("user") User user, HttpServletRequest request) {
    userService.update(user);
    return messageSource.getMessage("user.data_updated", null, request.getLocale());
}

ユーザーPOJOの実装は次のとおりです

@Entity
public class User implements Serializable {
...

@OneToMany(targetEntity = Language.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<Language> languages = new AutoPopulatingList(Language.class);
...
}

私のコントローラーに送られるPOSTリクエストは次のようになります(追加、言語2が追加されました):

languages[0].code:pl
languages[0].level:Fluent
languages[1].code:de
languages[1].level:Native
languages[2].code:cc
languages[2].level:Intermediate

および削除 (JQuery .remove()メソッドを使用して言語 1 を削除):

languages[0].code:pl
languages[0].level:Fluent
languages[2].code:cc
languages[2].level:Intermediate

したがって、通信側からは問題ないように見えますが、updateUser メソッドで @ModelAttribute("user") から取得したユーザーには、まだ 3 つの言語要素があり、すべて有効です (null ではありません)。助言がありますか?関連する場合は、Spring 3.1.1 と JQuery 1.7.2 を使用しています。

編集: フィールドを追加/削除するためのクライアント側のコードは次のとおりです。

$.addLanguage = function()  {
            var newLanguage = $('<input type="text" id="languages' + languagesCounter + '.code" name="languages[' + languagesCounter + '].code" class="langIdentifier"/>' +
                                '<select id="languages' + languagesCounter + '.level" name="languages[' + languagesCounter + '].level" class="langSelect">'  +
                                    '<option value="Basic">Basic</option>' +
                                    '<option value="Intermediate">Intermediate</option>' +
                                    '<option value="Fluent">Fluent</option>' +
                                    '<option value="Native">Native</option>' +
                                '</select>' +
                                '<input type="button" id="remove' + languagesCounter + '" onclick="$.removeLanguage(' + languagesCounter + ')"' +
                                        'name="Remove" value="Remove" class="removeButton"/>' +
                                '<br/>');
            languagesCounter++;
            newLanguage.insertBefore($("#add"));
        }

および削除の場合:

$.removeLanguage = function(languageId) {
    var languageField = '#languages' + languageId + '\\.code';
    var levelField = '#languages' + languageId + '\\.level';
    var removeButton = '#remove' + languageId;
    $(languageField).fadeOut(250, function() { $(this).remove(); });
    $(levelField).fadeOut(250, function() { $(this).remove(); });
    $(removeButton).fadeOut(250, function() { $(this).remove(); });
};
4

4 に答える 4

0

私自身の質問に答える(おそらく誰かの頭痛の種を救う):

私が持っていました

@ModelAttribute("user")
public User getUserById(@PathVariable("id") int id) {
    logger.fine("Getting user for id: " + id);
    return userService.findById(id);
}

GETでモデルにデータを入力し、

@RequestMapping(value = "/user/{id}", method = RequestMethod.POST)
@ResponseBody
public String updateUser(@PathVariable("id") int id, @ModelAttribute("user") User user, HttpServletRequest request) {
    userService.update(user);
    return messageSource.getMessage("user.data_updated", null, request.getLocale());
}

ユーザーを更新します。現在、問題全体はPOSTハンドラーの@ModelAttributeにありました。これは、事前入力コードの場合と同じ名前のキーにすることはできません。@ModelAttribute( "updated")と言うように変更すると、問題が解決しました。これで、フォームから削除されたオブジェクトは実際にnullになります。

今、私は永続化する前にリストからそれらを削除するのに苦労しています。

removeAll(Collections.singleton(null));

動作しないようです。

于 2012-06-24T17:01:01.177 に答える
0

AutoPopulatingListの代わりにLazyListを使用してみてください。これを使用して動的コンテンツを html に追加し、データをモデル属性オブジェクトに戻します。以下は、リストを作成するために使用しているコードです。

    private List<OperationParameters> operationParameterses = LazyList.decorate(new ArrayList<OperationParameters>(), FactoryUtils.instantiateFactory(OperationParameters.class));

    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY, mappedBy="operations")
    public List<OperationParameters> getOperationParameterses() {
        return this.operationParameterses;
    }

    public void setOperationParameterses(List<OperationParameters> operationParameterses) {
        this.operationParameterses = operationParameterses;
    }

そして、コントローラーでモデル属性にデータが入力されたリストを取得すると、最初にリスト内の空のデータをチェックし、次のコードでそれらを削除してからデータベースに保持します。それ以外の場合は、データベースに null データを挿入しようとします。

operations.getOperationParameterses().removeAll(Collections.singleton(null));

これがお役に立てば幸いです。乾杯。

于 2012-06-12T09:54:31.613 に答える
0

jqueryを使用してビューからリスト要素タグを削除する場合、その要素に新しい値をバインドするのを止める唯一のスプリングです。ただし、コントローラーのリストから要素を削除することはありません。

わかりやすくするために、jsp + spring がデータをリスト要素にバインドする方法を次に示します。リストの i 番目の要素をバインドするには、list.get(i).set(newVal) を呼び出します。したがって、ビューから i 番目の要素を削除すると、何もバインドされませんが、同時に i 番目の要素も削除されません。

削除するには、要素を削除するたびに ajax リクエストを送信し、コントローラーのリストから要素を削除します。

于 2014-07-08T19:30:06.277 に答える