1

全て、

チェックボックスと ASP.MVC に関する多くの投稿を読みましたが、それほど賢くはありません。

私のシナリオ:

for-each でレンダリングするために、サマリー オブジェクトのコレクションをビューに渡す、厳密に型指定されたビューがあります。この集計オブジェクトには、一意の ID に基づくラベル データが含まれています。また、行にチェックボックスを追加するので、次の方法で行います。

<td>
    <%= Html.CheckBox("markedItem", Model.MarkedItem, new { TrackedItemId = Model.Id })%>
</td>

送信された結果を取得するために POST を実行すると、アクション メソッドは厳密に型指定された ViewModel を取得しますが、リストの作成に使用した元のサマリー オブジェクトは取り込まれません。

わかりました、これは面倒ですが、理由は理解できるので、我慢します。

次に、文字列コレクションである "MarkedItem" という新しいプロパティを ViewModel に追加します。

ポストバック時に、チェックボックスが変更された場合、このマークされたアイテムは前後の状態で満たされますが、それらがどのキー用であったかはわかりません。明確にするために、これを送ると

  • TrackedItemId = A、値 = false
  • TrackedItemId = B、値 = true
  • TrackedItemId = C、値 = false

ページを次のように設定します。

  • TrackedItemId = A、値 = true
  • TrackedItemId = B、値 = true
  • TrackedItemId = C、値 = false

私はこれを返します:

  • MarkedItem[0] = true
  • MarkedItem[1] = false
  • MarkedItem[2] = true
  • MarkedItem[3] = false

つまり、[0] は新しい値、[1] は古い値、[2] と [3] は変更されていない値を表します。

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

  1. このように前と後に取得するのは正しいですか?最新の値のみを送信する方法はありますか?
  2. 返される文字列配列に意味を追加できるように、追加したカスタム属性 (TrackedItemId) を取得するにはどうすればよいですか?

これまでのところ、私は MVC が好きですが、このような単純なものを処理しないのは本当に混乱します。私はJavaScript初心者でもあるので、カスタムビューモデルでデータを返したいので、それが答えではないことを本当に願っています。

説明/アドバイスを簡単にしてください:)

4

2 に答える 2

0

わかりました、私が思いついた1つのハック-これをしなければならないのは本当に嫌いですが、それを回避する別の方法は見当たらず、いつか壊れると確信しています。

他のいくつかの問題 (たとえば、プロパティとしてのクラス) を回避するために、独自の ModelBinder によって既に実装しているので、このコードを組み込むように拡張しました。すべてのキーに Guid を使用します。

以下に代わるものがある場合は、お知らせください。

HTML

<%= Html.CheckBox("markedItem" + Model.Id, false)%>

C#

(GuidLength は const int = 36、左と右は独自の文字列拡張です)

//Correct checkbox values - pull all the values back from the context that might be from a checkbox. If we can parse a Guid then we assume
//its a checkbox value and attempt to match up the model. This assumes the model will be expecting a dictionary to receive the key and 
//boolean value and deals with several sets of checkboxes in the same page

//TODO: Model Validation - I don't think validation will be fired by this. Need to reapply model validation after properties have been set?    
Dictionary<string, Dictionary<Guid, bool>> checkBoxItems = new Dictionary<string, Dictionary<Guid, bool>>();

foreach (var item in bindingContext.ValueProvider.Where(k => k.Key.Length > GuidLength))
{
    Regex guidRegEx = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
        if (guidRegEx.IsMatch(item.Key.Right(GuidLength)))
        {
            Guid entityKey = new Guid(item.Key.Right(GuidLength));
            string modelKey = item.Key.Left(item.Key.Length - GuidLength);

            Dictionary<Guid, bool> checkedValues = null;
            if (!checkBoxItems.TryGetValue(modelKey, out checkedValues))
            {
                checkedValues = new Dictionary<Guid, bool>();
                checkBoxItems.Add(modelKey, checkedValues);
            }
        //The assumption is that we will always get 1 or 2 values. 1 means the contents have not changed, 2 means the contents have changed
        //and, so far, the first position has always contained the latest value
            checkedValues.Add(entityKey, Convert.ToBoolean(((string[])item.Value.RawValue).First()));
        }
}

foreach (var item in checkBoxItems)
{
    PropertyInfo info = model.GetType().GetProperty(item.Key,
            BindingFlags.IgnoreCase |
            BindingFlags.Public |
            BindingFlags.Instance);

        info.SetValue(model, item.Value, null); 
}
于 2010-02-08T19:01:35.513 に答える
0
<p> 
<label> 
   Select project members:</label> 
<ul> 
    <% foreach (var user in this.Model.Users) 
       { %> 
    <li> 
        <%= this.Html.CheckBox("Member" + user.UserId, this.Model.Project.IsUserInMembers(user.UserId)) %><label 
            for="Member<%= user.UserId %>" class="inline"><%= user.Name%></label></li> 
    <% } %></ul> 

そしてコントローラーで:

    // update project members        
foreach (var key in collection.Keys)     
{        
        if (key.ToString().StartsWith("Member")) 
        { 
                int userId = int.Parse(key.ToString().Replace("Member", ""));    
                if (collection[key.ToString()].Contains("true"))         
                        this.ProjectRepository.AddMemberToProject(id, userId); 
                else 
                        this.ProjectRepository.DeleteMemberFromProject(id, userId); 
        } 
} 

ピノのおかげで:)

于 2010-02-08T16:02:34.003 に答える