アプリ版:「スタンプのみでお礼する」機能のリリースについて

いつもお世話になります。
ASP.NET MVCを使って構築中のサイトで、また暗礁に乗り上げております。

商品一覧の画面で、一覧表示のままCRUD(追加・更新・削除)するインターフェースを客先から求められております。
一覧表示 → 個別画面でのCRUDはできていますが、画面遷移が面倒ということで却下されました。
ASP.NETでいう、GridViewのようなテイストです。
(各行にテキストボックス・更新ボタン・削除ボタン)

モデルはこんな感じです(簡略化してあります。実際にはご教示いただいたカスタム検証もあります)
public class Lady
{
 public int ID { get; set; }
 public string name { get; set; }
 public int areaID { get; set; }
 public int salesAmount { get; set; }
}
public List<Lady> ladies;

一覧表部分のビューはこんな感じです(細かい点は省略です)

@foreach (var lady in Model.ladies){
 @using(Html.BeginForm("UpdateLady","Admin")) {
  @Html.Hidden("ID", lady.ID)
  @Html.TextBox("name", lady.name)
  @Html.DropDownList("areaID", new SelectList(model.areas, "areaID","areaName", lady.areaID))
  @Html.TextBox("salesAmount",lady.salesAmount)
  <!-- 以降不明 -->
  <input type="submit" value="更新"/>
  <input type="submit" value="削除"/>
 }
}

コントローラ

class AdminController
{
 public EditLady(){
  var model = new EditLadyView();
  return View("EditLady", model);
 }

 [HttpPost]
 public UpdateLady(Lady lady){
  if (ModelState.IsValid){
   // 更新
   // lady.IDをキーにしてDBを更新
  } else {
   // 再表示 <!-- ここがわからない -->
  }
 }

 [HttpPost]
 public DeleteLady(int ID){
  // 削除
  // IDをキーにしてDBを削除
 }

}


質問点は以下の通りです。

■表示はOKですが、できたhtmlを見ると、各行の項目が同じid / name名になります。これで正しいですか?
■同じForm内に更新ボタンが複数あった場合、formのPOST先を変える必要がありますが、javascriptを使うのでしょうか?
■検証失敗時、全体を再表示するにはどういった方法があるでしょうか? 読み直すと入力した値が消えてしまいます。

会社にMVCの経験者がおらず、苦労しています。
なにとぞお助けください。

A 回答 (4件)

こんにちは。


一覧で表示し、更新は一行単位というのは、GridViewやListViewではよくやる処理です。
項目数が少なく行数が限定的な場合を除き、全体一括更新は使ってはいけません!

要点だけ述べます。
ご謙遜されていますが、MVCの内容ををお分かりのようなので、自分で解決策を考えてください。

1 こんな風にレンダリングされるフォームを作ります。
<input type="hiddden" name="ID" value="1012" />
<input type="text" name="1012.name" value="東京花子" />
<input type="text" name="1012.address" value="千代田区一丁目一番地" />

2 更新メソッドで、いきなりLady型のladyで受けず、IDだけを取得します。
3 取得したIDを接頭辞(prefix)として、表示に使ったビューモデルの指定ID行を、TryUpdateModelで更新します。
4 ModelStateは、TryUpdateModelでも有効です。
5 DB更新はただUpdateすればいいだけ
6 検証失敗時のリトライは、更新できなかったビューモデルをそのまま返します。

ASP.NET MVC3関連の洋書には、こういうTable CRUDの話題が良く出ています。
英語読まなあかんのですが。。苦(笑
    • good
    • 0
この回答へのお礼

詳細なアドバイスをいただき、ありがとうございます。
情けないことに、まだ問題を解決できていません。
今回なんとか、お客様に個別更新で納得いただきました。
自分の力量不足で情けないです。
でも必ず、この問題はクリアしようと思っていますので、また不明点があったらつきあってやって下さい。

お礼日時:2012/12/28 16:31

> まことにお恥ずかしい限りですが、では、どのように更新画面を組み立てれるべきだと思われますか?



仕様の話なんで、お客さん(利用者?)とつめるべきでしょう。

MVCで組みやすく、一覧形式は保持したい、ということなら

> ・一覧表表示での1行更新という仕様に問題がある。全体一括更新にすべき。

となるかな。

ちなみに、別に「泥臭い」のが悪いとはおもってません。
仕様というかお客様のこだわりで、実装は泥臭いコーディングにせざるを得ないなんてことはいくらでもあることですから。
    • good
    • 0
この回答へのお礼

onosさま、いつも有難うございます。
自分の力量不足で、一括更新を実現することができませんでした。
前にGridViewで何回もやっていた処理なので、なんでMVCでできないのか、もう一度よく考えてみます。
今回は有難うございました。

お礼日時:2012/12/28 16:35

> 一つのformに「更新」と「削除」のボタンが2つ出てくるのですが、そもそも各行ごとにformをつけるのは適正なのか? という点もわからないです。



別にformはいくつあってもかまわないと思います。

> 更新行は1行だけなのですが、検証エラー時も、再度、対象の1画面分のデータはすべて再取得しなければいけませんか?

formを各行に設定した場合、ブラウザから投げられるのは更新行のデータだけです。
サーバー側には他のデータを取得する方法はありません。

#HTMLがステートレス、というのは理解されてますよね?

まぁ、SessionだのTmpData(は、つまりSessionと同じですが)を使ってサーバ側にデータを保持しておく方法がないわけではないですが。
それであってもある意味データを再取得している、といえなくもないわけで。

あと、こういうユーザーインターフェースだと、2行文のデータなおしたあと、1行めの更新ボタンだけ押したとき、とか、いろいろと問題は多くでてきそうな気がします。
まぁ、仕様としてどう考えるか、なのでそういったときの対処方法がきちんと合意されていればよいですが。

> ASP.NETのような「サーバサイド検証」や「バインディング」の機能がないため、泥臭い大量コーディングを強いられます

この仕様だと検証やバインディングもうまく使えない、というか使えるところが限られてくるかと。
泥臭いコーディングが必要じゃないですかね。

この回答への補足

onos様、何度もありがとうございます。
本当に有難うございます(感涙

> formを各行に設定した場合、ブラウザから投げられるのは更新行のデータだけ

はい、存じております。理解できました。

> この仕様だと検証やバインディングもうまく使えない、というか使えるところが限られてくるかと。
> 泥臭いコーディングが必要じゃないですかね。

まことにお恥ずかしい限りですが、では、どのように更新画面を組み立てれるべきだと思われますか?

・一覧表表示での1行更新はOK。フォームやHtmlヘルパーの設定の仕方に問題がある。
・一覧表表示での1行更新という仕様に問題がある。全体一括更新にすべき。
・一覧表表示での更新自体に問題がある。

本当に困っています。失礼とは存じますが、ご意見お聞かせください。

補足日時:2012/12/06 17:20
    • good
    • 0

> ■表示はOKですが、できたhtmlを見ると、各行の項目が同じid / name名になります。

これで正しいですか?

OKじゃないから質問してるのでは?
それはともかく、どのようなデータを渡しているのか、またView側の受け取るデータの型がどうなっているか、とかが掲載されたプログラムだけじゃわかりません。
ちゃんと複数のデータ格納して渡せてます?

> ■同じForm内に更新ボタンが複数あった場合、formのPOST先を変える必要がありますが、javascriptを使うのでしょうか?

行ごとに存在する更新ボタンのことですよね?
だったらformのPOST先を変える必要はないように思いますが。。。

> ■検証失敗時、全体を再表示するにはどういった方法があるでしょうか? 読み直すと入力した値が消えてしまいます。

UpdateLady で受け取っているデータが一つだけなのが気になります。
ここで全データ受け取ってるならそのままもとのページに返せばいいだけのはず。
まぁ、どの部分を変更しようとしているか、という対象のとりだしに工夫が必要ですが。
データを一つしか受け取らないなら、他の行については再度取得してビュー側に渡す必要があると思います。

この回答への補足

いつもありがとうございます。
ちょっと説明不足ですいませんでした。「一覧表示」しつつ、各行に更新・削除ボタンのあるインターフェースをMVCで作りたいのです。

表示するまでは問題ありません。
Model側にEditLadyViewというビュークラスを定義し、Controllerで初期化する際、ladiesプロパティに、取得したList<Lady>型を入れています。

一つのformに「更新」と「削除」のボタンが2つ出てくるのですが、そもそも各行ごとにformをつけるのは適正なのか? という点もわからないです。

phpなどですと、
<form action="update_lady">
 <input name="ID" type="hidden" />
 <input name="name" type="text"/>
</form>
(以降繰り返し)
のように単純にタグ発生させるます(ASP.NETのような「サーバサイド検証」や「バインディング」の機能がないため、泥臭い大量コーディングを強いられます)。

こういう「行更新」をともなう集合型?のフォームについて知りたいです。
更新行は1行だけなのですが、検証エラー時も、再度、対象の1画面分のデータはすべて再取得しなければいけませんか?

補足日時:2012/12/06 14:56
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています