Asp.Net MVC 5 Fill EditorFor при изменении выпадающего списка SelectedItem

Мне нужно заполнить элементы управления Html.EditorFor, когда я выбираю продукт из раскрывающегося списка. Я очень новичок в JQuery и Ajax.

Мое раскрывающееся меню:

@Html.DropDownList("ProductId", null, htmlAttributes: new { @class = "form-control", 
@onchange= "FillPrice()", id= "ProductId" })

РедакторДля:

@Html.EditorFor(model => model.ProductPrice, 
                new { htmlAttributes = new { 
                           @class = "form-control",  
                           id="txtPrice" } })

JavaScript:

function FillPrice() {
    var ProductId = $('#ProductId').val();
    $.ajax({
        url: '@Url.Action("GetPrice")',
        dataType: "JSON",
        data: { ProductId: ProductId },
        contentType: "application/json; charset=utf-8",
        success: function (price) {
            $('#txtPrice').val()   ??? What to write here to fill txtPrice?
        }
    });  
  }

Контроллер/Получить цену:

public JsonResult GetPrice(int ProductId)
{
    var price = from r in db.Products
                where r.Id == ProductId
                select new { 
                     id = r.Id, 
                     label = r.ProductPrice, 
                     value = r.ProductPrice };
    return Json(price, JsonRequestBehavior.AllowGet);
}

До этого момента все работает. Я проверяю с помощью Firebug и вижу получение и результаты Json, но я не могу привязать значение к EditorFor.


person degergio    schedule 30.09.2015    source источник
comment
$('#txtPrice').val(price.value) - но почему вы возвращаете 2 свойства (label и value) с одинаковым значением? Вы также можете удалить опцию contentType:   -  person    schedule 30.09.2015
comment
Добавьте: success: function (price) { console.dir(price); и посмотрите, какие свойства есть у price.   -  person freedomn-m    schedule 30.09.2015
comment
Я удалил блок contentType, а также свойства label= r.ProductPrice. Затем я попробовал '$('#txtPrice').val(price.value)', но не работает.   -  person degergio    schedule 30.09.2015


Ответы (1)


Ответ в вашем JavaScript находится в переменной price:

function (price) {
    //...
}

Судя по серверному коду, этот объект имеет три значения:

new { 
    id = r.Id, 
    label = r.ProductPrice, 
    value = r.ProductPrice }

(Я не уверен, почему вам нужно одно и то же значение дважды, но что угодно.)

Итак, вы, вероятно, ищете свойство value этой переменной?:

$('#txtPrice').val(price.value);

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


Изменить: похоже, что возвращаемое значение может быть массивом. Что имеет смысл, учитывая, что код на стороне сервера приводит к ошибке IEnumerable<>. Если он должен возвращать только одно значение, вы можете указать это явно. Что-то вроде этого:

return Json(price.Single(), JsonRequestBehavior.AllowGet);

Вы захотите добавить некоторую проверку ошибок вокруг этого, и логика обработки ошибок (несколько найденных значений или не найденное значение) зависит от вас.

И наоборот, если вы хотите, чтобы это был массив, вы должны обращаться к нему как к массиву на стороне клиента:

$('#txtPrice').val(price[0].value);

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

person David    schedule 30.09.2015
comment
С помощью отладчика Google Chrome на вкладке «Сеть» я вижу этот результат: [{id: 14, значение: 24}]. Но $('#txtPrice').val(price.value); не дает мне значение: 24 - person degergio; 30.09.2015
comment
@degergio: судя по выходным данным отладчика, price — это массив. Попробуйте: price[0].value вместо этого. Хотя вы можете изменить код на стороне сервера, чтобы он возвращал одно значение, если вы ожидаете только одно значение. - person David; 30.09.2015
comment
О, спасибо. Это сработало для меня. $('#txtPrice').val(цена[0].value); дал мне результат. Если вы отредактируете свой ответ, я отмечу его как ответ, чтобы помочь другим. - person degergio; 30.09.2015
comment
@degergio: Ответ теперь обновлен несколькими вариантами. Я рекомендую соответствующим образом изменить код на стороне сервера, чтобы API открывал то, что вы от него ожидаете. Но это зависит от вас и от того, как вы хотите структурировать свой API (и где вы хотите инкапсулировать любую проверку ошибок и защитное программирование). - person David; 30.09.2015
comment
При определении продукта требуется указать цену, а раскрывающийся список заполняется только существующими продуктами. Таким образом, нет никаких шансов получить нулевой или пустой ответ, если вы выберете продукт из этого выпадающего списка. - person degergio; 30.09.2015
comment
@degergio: маленький шанс, но есть a шанс. Даже из-за, возможно, ошибки в логике в другом месте потребляющей страницы. Хорошо обработанная ошибка облегчает отладку. - person David; 30.09.2015
comment
Могу ли я добавить 2 $.ajax для функций FillPrice()? Например, теперь я получаю ProductPrice из таблицы Products, но я также хочу получить ProductStockQuantity из таблицы Stocks. Можно ли добавить 2 URL-адреса: «@Url.Action(GetPrice)» и URL-адрес: «@Url.Action(GetQuantity)» внутри функции FillPrice()? - person degergio; 30.09.2015
comment
@degergio: вы можете делать столько вызовов AJAX, сколько хотите. Хотя, вероятно, имеет смысл иметь только один вызов AJAX, который возвращает все данные, которые вам понадобятся. Если второй вызов не зависит от результатов первого вызова, нет необходимости в накладных расходах на 2 вызова. - person David; 30.09.2015