2013-04-18 2 views
1

У меня возникли проблемы с привязкой моей модели к ящику ввода, созданному пользовательским вспомогательным методом. Я завернул блок автозаполнения jquery ajax с помощью вспомогательного метода под названием «Html.AutoCompleteBoxAjax». Этот помощник в принципе просто создает элемент с функцией автозаполнения javascript.Невозможно связать свойство модели MVC с элементом ввода

Свойство в модели представляет собой строку под названием «formatName». Я проверил, что в сгенерированном html для представления оба имени и идентификатора входного элемента являются «formatName» и что нет других элементов с этими идентификаторами. Я также проверил, что модель имеет конструктор по умолчанию, и свойство "formatName" является общедоступным. Наконец, я подтвердил, что, когда модель канала передается в представление, значение Channel.formatName имеет правильное значение. Тем не менее, несмотря на все это, я не могу получить значение для привязки к элементу, и поле ввода остается пустым. Также нет привязки при переходе с другого пути, от представления к контроллеру, а Channel.formatName остается пустым.

Что мне не хватает? Это почему-то, потому что я использую собственный вспомогательный метод?

Модель:

namespace WebApp.Models 
{ 
    public class ChannelModel 
    { 
     XYZ.DataAccess.ODS.DB db = Config.DB(); 

     public string id { get; set; } 

     // Parent Project 
     [Display(Name = "Project")] 
     public string projectID { get; set; } 

     // Format Name 
     [Required(ErrorMessage = "Format is required.")] 
     [RegularExpression(Constants.username_regex, ErrorMessage = Constants.username_regexErrorMsg)] 
     [Display(Name = "Format")] 
     public string formatName { get; set; } 

     // Channel Name 
     [Required(ErrorMessage="Channel name is required.")] 
     [StringLength(100, ErrorMessage = Constants.minLengthErrorMsg, MinimumLength = Constants.username_minLength)] 
     [RegularExpression(Constants.username_regex, ErrorMessage = Constants.username_regexErrorMsg)] 
     [Display(Name = "Channel name")] 
     public string name { get; set; } 

     // Sequence 
     [Display(Name = "Sequence")] 
     public string sequenceID { get; set; } 

     public ChannelModel() 
     { 
      id = Guid.NewGuid().ToString(); 
     } 

     public ChannelModel(XYZ.DataAccess.ODS.Channel channel_db) 
     { 
      id = channel_db.id; 
      projectID = channel_db.project_id; 
      name = channel_db.name; 
      formatName = channel_db.format_name; 
      sequenceID = channel_db.sequence_id; 
     } 

     public XYZ.DataAccess.ODS.Channel buildDBObject() 
     { 
      XYZ.DataAccess.ODS.Channel channel = new XYZ.DataAccess.ODS.Channel(); 
      channel.id = id; 
      channel.project_id = projectID; 
      channel.name = name; 
      channel.format_name = formatName; 
      channel.sequence_id = sequenceID; 
      return channel; 
     } 
    } 


} 

Посмотреть

@model WebApp.Models.ChannelModel 
@using HelperMethods.Infrastructure 

@{ 
    ViewBag.Title = "Edit"; 

    var sequences = ViewData["sequences"] as List<SelectListItem>; 
} 

<h2>Edit</h2> 

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script> 
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script> 

@section header { 
} 

@using (Html.BeginForm()) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Channel</legend> 

     @Html.HiddenFor(model => model.id) 
     @Html.HiddenFor(model => model.projectID) 
     @Html.HiddenFor(model => model.name) 

     <div class="editor-field"> 
      @Html.LabelFor(model => model.name): 
      @Html.DisplayFor(model => model.name) 
     </div> 

     <div class="editor-label"> 
      @Html.Label("Format") 
     </div> 
     <div class="editor-field"> 
      @Html.AutoCompleteBoxAjax("formatName", Url.Action("GetFormatsBeginningWith")) 
      @Html.ValidationMessageFor(model => model.formatName) 
     </div> 

     <!-- SEQUENCE --> 
     <div class="editor-label"> 
      @Html.Label("Sequence") 
     </div> 
     <div class="editor-field"> 
      @Html.SlaveDropdownList("sequenceID", "groupID", Url.Action("GetSequencesInGroup"), WebApp.Util.makeSelectList(sequences, Model.sequenceID)) 
     </div> 


     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

Контроллер

namespace WebApp.Controllers 
{ 
    public class ChannelController : Infrastructure.NoCacheController 
    { 
     XYZ.DataAccess.ODS.DB db = Config.DB(); 

     -- stuff -- 

     [HttpGet] 
     public ActionResult GetFormatsBeginningWith(string term) 
     { 
      var formats = db.getFormatsBeginningWith(term); 

      List<CustomHelpers.AutocompleteItem> items = new List<CustomHelpers.AutocompleteItem>(); 
      foreach (var format in formats) 
       items.Add(new CustomHelpers.AutocompleteItem { value = format.name, label = format.name }); 

      var j = Json(items, JsonRequestBehavior.AllowGet); 
      return j; 
     } 


     public ActionResult Edit(string id) 
     { 
      ChannelModel channelModel = new ChannelModel(db.getChannel(id)); 

      string groupID = db.getProject(channelModel.projectID).group_id; 
      var sequences = db.getSequencesInGroup(groupID); 
      ViewData["sequences"] = makeSelectListItems(sequences); 

      return View(channelModel); 
     } 

     // 
     // POST: /Channel/Edit/5 

     [HttpPost] 
     public ActionResult Edit(ChannelModel model) 
     { 
      if (ModelState.IsValid) 
      { 
       db.updateChannel(model.buildDBObject()); 

       return RedirectToAction("Index"); 
      } 

      string groupID = db.getProject(model.projectID).group_id; 
      var sequences = db.getSequencesInGroup(groupID); 
      ViewData["sequences"] = makeSelectListItems(sequences); 

      return View(model); 
     } 

     -- more stuff -- 
    } 
} 

Вспомогательный метод для AutoCompleteBox

public static MvcHtmlString AutoCompleteBoxAjax(this HtmlHelper html, string id, string actionUrl) 
    { 
     TagBuilder input = new TagBuilder("input"); 
     input.Attributes.Add("id", id); 
     input.Attributes.Add("name", id); 
     input.Attributes.Add("type", "text"); 
     input.AddCssClass("autocomplete_ajax"); 
     input.Attributes.Add("value", ""); 
     input.Attributes.Add("action", actionUrl); 

     var variables = new Dictionary<string, string>() { 
      {"AUTOCOMPLETE_ID", id} 
     }; 

     var script = populateScriptTemplate("TEMPLATE_autocomplete_ajax.js", variables); 

     StringBuilder s = new StringBuilder(); 
     s.AppendLine(input.ToString(TagRenderMode.SelfClosing)); 
     s.AppendLine(script); 

     return new MvcHtmlString(s.ToString()); 
    } 

Javascript для автозаполнения

$('#AUTOCOMPLETE_ID').autocomplete({ 
    source: $('#AUTOCOMPLETE_ID').attr('action') 
    }); 

Соответствующая часть HTML отображения вида

<div class="editor-field"> 
    <input action="/Channel/GetFormatsBeginningWith" class="autocomplete_ajax" id="formatName" name="formatName" type="text" value="" /> 
    <span class="field-validation-valid" data-valmsg-for="formatName" data-valmsg-replace="true"></span> 
</div> 
+0

Если вы являетесь предварительно заполняющими входами и другими элементами формы, то помощник должен правильно установить значение. Нет «после обработки», который позаботился об этом или о любом автоматическом процессе. Я бы рекомендовал вызывать встроенный помощник TextBox/TextBoxFor из вашего AutoCompleteBoxAjax и только предустановить для него параметры. – Jakub

+0

О, конечно. Каким-то образом я понял, что причина, по которой помощники были определены как методы расширения, заключалась в том, чтобы сохранить какой-то механизм, с помощью которого связывалось волшебство. Очевидный в ретроспективе. Спасибо. – Gadzooks34

ответ

1

Ответ оказался прост при участии @Jakub. Помощник сам должен заполнить значение; нет автоматической привязки, которая имеет место для html-помощников. Как только я позаботился об этом, автоматическое связывание сообщений с контроллером работало так, как ожидалось.

Смежные вопросы