.NET Core ‹выбрать› со значением по умолчанию?

Моя цель состоит в том, чтобы создать раскрывающийся список <select> с предварительно выбранным определенным значением выбора (<option>), поэтому окончательный вариант HTML должен выглядеть так:

<select>
  <option value = "1">Option1</option>
  <option value = "2" selected>Option2</option>
  <option value = "3">Option3</option>
</select>

Обратите внимание, что параметр со значением 2 имеет атрибут selected, указывающий, что он будет отображаться до того, как будет нажат раскрывающийся список. Я не могу (и пытаюсь) добиться этого с помощью .NET Core Tag Helpers.

Это моя модель (думаю, вы можете смело игнорировать детали):

public class ReportViewModel
{
  [Display(Name = "Pick a form")]
  public IEnumerable<Form> AvailableForms { get; set; }

  public Form SelectedForm { get; set; }

  public List<ReportData> FormResponses { get; set; }
}

Обратите внимание, что объект Form содержит только свойства Id и Name.

Это мой оператор выбора:

<label asp-for="SelectedForm.Name" class="form-control-label font-weight-bold"></label>
<select asp-for="SelectedForm.Name"
        class="form-control"
        onchange ="onFormSelected(this.value)"
        asp-items="@(new SelectList(Model.AvailableForms, "Id", "Name"))">
</select>

Я не вижу ответа в Руководство Microsoft Или в блог по теме


person VSO    schedule 13.12.2017    source источник
comment
Это для пустого состояния по умолчанию или вы пытаетесь отобразить выбранное значение (например, предпочтения пользователя, которые уже были выбраны)?   -  person James    schedule 13.12.2017
comment
@James Пользователь выбирает форму на другой странице. Эта страница (с разметкой) выше загружается. Цель состоит в том, чтобы они могли выбрать другую форму для отчета, если захотят. Короче говоря, у меня есть идентификатор формы по умолчанию в контроллере до загрузки представления.   -  person VSO    schedule 13.12.2017
comment
Значение asp-for будет определять, что изначально выбрано.   -  person Cake or Death    schedule 13.12.2017
comment
Спасибо @CalC, пробую сейчас. Раньше я предполагал, что это так.   -  person VSO    schedule 13.12.2017


Ответы (3)


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

<label asp-for="SelectedForm" class="form-control-label font-weight-bold"></label>
<select asp-for="SelectedForm.Id"
        class="form-control"
        onchange ="onFormSelected(this.value)"
        asp-items="@(new SelectList(Model.AvailableForms, "Id", "Name"))">
</select>

Затем в вашем контроллере

var vm = new ReportViewModel()
{
    AvailableForms = new List<Form>()
};

var form2 = new Form() { Id = 2, Name = "Bar" };
(vm.AvailableForms as List<Form>).Add(new Form() { Id = 1, Name = "Foo" });
(vm.AvailableForms as List<Form>).Add(form2);
(vm.AvailableForms as List<Form>).Add(new Form() { Id = 3, Name = "Baz" });

vm.SelectedForm = form2;

return View(vm);
person Tony Ranieri    schedule 13.12.2017

Конструктор SelectList может принимать дополнительный аргумент, а именно selectedValue. В вашем случае вы должны пройти через это, что, думаю, будет выглядеть примерно так:

asp-items="@(new SelectList(Model.AvailableForms, "Id", "Name", Model.SelectedForm.Id))"

Я думаю, что причина, по которой asp-for у вас не работает, заключается в несоответствии между значением SelectedForm.Name (который является строкой) и значением свойства Id, которое вы используете в конструкторе SelectList (которое является целым числом?).

Вы можете частично увидеть, как это работает в исходном коде. В итоге вы окажетесь здесь в GenerateOption:

var selected = item.Selected;
if (currentValues != null)
{
    var value = item.Value ?? item.Text;
    selected = currentValues.Contains(value);
}

На данный момент я считаю, что currentValues будет содержать один элемент, который будет строкой (Form.Name). Я также считаю, что item.Value будет, например. "1" и так совпадения нет.

person Kirk Larkin    schedule 13.12.2017

Это старо, но я не видел здесь своего подхода. Передайте его с помощью viewbag от контроллера.

<select>
    <option>@ViewBag.selected</option>
    <option>1</option>
    <option>2</option>
    <option>3</option>
</select>
person Nick Fleetwood    schedule 23.10.2020
comment
Ха-ха, может быть, еще через 3 года я снова воспользуюсь Razor, попробую и проголосую за него. - person VSO; 23.10.2020
comment
Если мое выбранное значение равно 2, теперь добавляются параметры 2,1,2,3. Это сбивает пользователей с толку тем, что теперь в списке есть дубликаты. Как удалить дубликат? - person tval; 13.01.2021