ASP.MVC 1.0 Значения флажка с ViewModel и для конкретного идентификатора - PullRequest
1 голос
/ 08 февраля 2010

All

Я прочитал много постов о флажках и ASP.MVC, но я не настолько мудр.

Мой сценарий:

У меня строго типизированное представление, в котором я передаю коллекцию объектов-сводок представлению для рендеринга в for-each. Этот сводный объект содержит данные метки на основе уникального идентификатора. Я также добавляю флажок в строку, поэтому сделайте это с помощью:

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

Когда я выполняю POST для получения отправленных результатов, мой метод действия возвращает строго типизированную ViewModel, но исходный объект сводки, который я использовал для создания списка, не заполняется.

Хорошо, это раздражает, но я могу понять, почему, поэтому я буду жить с этим.

Затем я добавляю в свой ViewModel новое свойство под названием «MarkedItem», которое представляет собой коллекцию строк.

При обратной передаче этот отмеченный элемент заполняется до и после состояния, если флажок был изменен, но ничего не говорит мне, для какого ключа они были. Просто чтобы уточнить, если я отправлю это

  • 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, поэтому я действительно надеюсь, что это не тот ответ, поскольку я хотел бы вернуть данные в моей пользовательской модели представления.

Пожалуйста, сделайте любые объяснения / советы простыми:)

Ответы [ 2 ]

0 голосов
/ 08 февраля 2010

хорошо, один взлом, который я придумал - я действительно ненавижу, что должен это делать, но я не вижу другого пути, и я уверен, что в какой-то момент он сломается.

Я уже реализовал собственный 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); 
}
0 голосов
/ 08 февраля 2010
<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); 
        } 
} 

С благодарностью Пино:)

...