Заполнение MVC DropdownList источником AJAX и привязка выбранного значения - PullRequest
0 голосов
/ 03 мая 2018

У меня есть вид для отображения информации об участнике. Внутри есть элемент EditorFor, который представляет предметы, взятые участником.

 @Html.EditorFor(m => m.Subject)

Внутри шаблона редактора есть Html.DropDownListFor (), который показывает выбранную тему и кнопку для удаления этой темы

Я использую элемент Html.DropDownListFor как:

@Html.DropDownListFor(m => m.SubjectID, Enumerable.Empty<SelectListItem>(), "Select Subject", 
new { @class = "form-control subjects" }) 

Второй параметр (источник) установлен пустым, поскольку я хочу загрузить источник из запроса AJAX; как показано ниже:

$.getJSON(url, function (response) {
         $.each(response.Subjects, function (index, item) { 
                $('.subjects').append($('<option></option>').text(item.Text).val(item.ID));
            });
         // code to fill other dropdowns
    });

В настоящее время HTML загружается до того, как раскрывающиеся списки заполнены. Таким образом, значения всех выпадающих списков по умолчанию устанавливаются на «Выбрать тему» ​​по умолчанию. Есть ли способ обойти это или это неправильный подход?

Примечание : на этой странице есть несколько выпадающих меню. Вот почему я предпочел бы загрузить им AJAX-запрос и кэшировать его вместо того, чтобы вставлять viewModel и заполнять его для каждого запроса.

** РЕДАКТИРОВАТЬ **

При вызове AJAX действие возвращает объект json, содержащий раскрывающиеся списки, используемые на всех страницах. Это действие украшено [Output Cache], чтобы избежать частых поездок на сервер. Изменен код в $.each, чтобы отразить это.

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Можно изначально присвоить значение свойства переменной javascript и использовать его для установки значения выбранного параметра в обратном вызове ajax после добавления параметров.

// Store initial value
var selectedId = @Html.Raw(Json.Encode(Model.Subject.SubjectID))
var subjects = $('.subjects'); // cache it

$.getJSON(url, function (response) {
    $.each(response, function (index, item) { 
        subjects.append($('<option></option>').text(item.Text).val(item.ID));
    });
    // Set selected option
    subjects.val(selectedId);
});

Однако неясно, почему вы делаете вызов ajax, если только вы не генерируете каскадные выпадающие списки, что, похоже, не так. То, что вы делаете, в основном говорит клиенту - вот некоторые данные, но я забыл отправить то, что вам нужно, поэтому потратьте еще немного времени и ресурсов на установление другого соединения для получения остальных данных . И ты ничего не кешируешь, несмотря на то, что думаешь.

Если, с другой стороны, ваше свойство Subject фактически является набором объектов (в этом случае оно должно быть Subjects - множественное число), то правильный вариант с использованием EditorTemplate объясняется в варианте 1 этот ответ .


Обратите внимание также, что если Subject является коллекцией, то приведенный выше код var selectedId = .. необходимо изменить, чтобы сгенерировать массив значений SubjectID, например

var selectedIds = @Html.Raw(Json.Encode(Model.Subject.Select(x => x.SubjectID)))

, и тогда каждое значение выпадающего списка необходимо будет установить в цикле

$.each(subjects, function(index, item) {
    $(this).val(selectedIds[index]);
});
0 голосов
/ 04 мая 2018

Если ваш JSON сообщает вам, какую опцию они выбрали, вы можете просто сделать следующее после заполнения раскрывающегося списка:

$('.form-control.subjects').get(0).selectedIndex = [SELECTED_INDEX];

Где [SELECTED_INDEX] - это индекс элемента, который вы хотите выбрать внутри раскрывающегося списка.

...