On my current project I’ve been working with a concept called a time point, which allows a user to schedule certain events that need to happen at specific points of time. Up until now I had been using the same partial view rendered from different parent views (which were also partial views within an overall view). This caused problems when rendering fields using EditorFor and DropDownListFor methods, as these methods use the model name to create the field names and ids. Because the model was the same, fields called from different parent views were being rendered with the same names and ids. To work around this I had to use an if-else to decide on the prefix that we needed, depending on a certain property in the model which was set in the parent view. This approach was quite clunky and Editor templates negate the need for this as they render the correct ids and names automatically.

An Editor template is a partial view that’s placed by convention in a directory called “EditorTemplates” in Views/Shared, and again by convention is named the same as the view model containing the fields we want to render:

 

Image

 

So in this case my ViewModel is called DiscreteTimepointViewModel.cs:

/// <summary>
/// ViewModel for discrete timepoints
/// </summary>
public class DiscreteTimepointViewModel
{
/// <summary>
/// Gets or sets the TimePointType associated with this StudyEvent
/// </summary>
public int TimePointType { get; set; }
/// <summary>
/// Gets or sets a time points string which can serve as an input for generating an array of time points. This property
/// is only used by the razor views to generate HTML elements using the HTML helpers.
/// </summary>
public double? TimePoint { get; set; }
/// <summary>
/// Gets or sets the ID of the time unit for the specified TimePoint.
/// </summary>
[Required]
public int? TimeUnitID { get; set; }
/// <summary>
/// Gets or sets the model name
/// </summary>
public string ModelName { get; set; }
/// <summary>
/// Gets or sets the left hand field binding name
/// </summary>
public string LeftHandFieldBindingName { get; set; }
}

After adding the template view and view model I then add a view model property to each parent view that I want to render it from:

/// <summary>
/// Gets or sets the view model for discrete time points
/// </summary>
public DiscreteTimepointViewModel DiscreteTimePoint { get; set; }

So using the above I render the time point fields from a view as such:


@{Model.defaultStudyEvent = new DiscreteTimepointViewModel { TimeUnitID = 1, ModelName = "defaultStudyEvent", LeftHandFieldBindingName = "leftHandStudyEvent" }; }
@Html.EditorFor(x => x.defaultStudyEvent, "DiscreteTimepointViewModel")

 

About these ads