1

所以我有我做一些ajax的方法:

function prodChange() {
    console.log(this.value);

    // ajax
    var url = '@Url.Action("GetAdvProdList", "Contract")' + '?prod_id=' + this.value;
    $.ajax({
        url: url,
        type: 'GET',
        success: showAdvProd,
        error: function() {
            console.log("FAILSHAKUREHKGAHH");
        }
    });  
}

ajax 成功返回并调用此控制器方法。

public ActionResult GetAdvProdList(int prod_id) { // product id
        // get advertising products for this product
        OutlookMediaEntities1 db = new OutlookMediaEntities1();

        var advsList = from printAdOption in db.print_ad_option
                        where printAdOption.print_product_id == prod_id
                        select printAdOption;

        List<SelectListItem> adv_list = new List<SelectListItem>(); // list of ads
        List<print_ad_option> advs = advsList.ToList(); // list from db
        foreach (print_ad_option av in advs)
        {
            SelectListItem temp_item = new SelectListItem();
            temp_item.Text = av.name;
            temp_item.Value = av.print_ad_option_id.ToString();
            adv_list.Add(temp_item);
        }
        ViewData["advproducts"] = new SelectList((IEnumerable<SelectListItem>)adv_list.ToList(), "Value", "Text");

        return null;
    }

我正在返回 null,因为如果我返回 View 或 PartialView,它就不起作用,而且我认为我不希望它返回这些东西。我想要的只是要设置的视图数据。

在我添加代码以使用视图数据之前,ajax 运行良好。不幸的是,当我尝试在 ajax 成功方法中使用新的 ViewData 时,我收到此错误:“没有具有键 'print_ad_option_id' 的 'IEnumerable' 类型的 ViewData 项目”问题是我第一次收到此错误加载页面,因此它似乎试图在调用 showAdvProd 函数之前评估“@Html.DropDownListFor...”:

// called when the ajax returns a list of adv prods in a viewdata
function showAdvProd() {
    // add drop down
    $("#drdn1").append('@Html.DropDownListFor(m => m.print_ad_option_id, ViewData["advproducts"] as SelectList)');
}

当从(不同的)下拉菜单中选择一个项目时,会调用执行 ajax 的函数,但是由于此错误,页面甚至不会加载,因此显然永远不会调用 ajax 函数,因此永远不会调用控制器方法。所以当然它不会识别视图数据......

我同样在表单的另一部分创建了一个下拉菜单,使用 viewdata 但没有 ajax,它工作正常。所以我认为我的 ajax 或我的控制器方法有问题,而不是我使用 viewdata 的方式。

预先感谢您的任何帮助!

4

1 回答 1

0

@问题是在您的初始页面加载时,视图引擎将评估所有代码块 -前面带有“”符号的任何内容。因此,它会在它存在之前尝试查找名为advproducts的 ViewData 项,即使该引用位于尚未调用的 javascript 函数中。请记住 - 代码块(例如在@Html.blahblahblah()服务器端评估,而您希望 ajax 在客户端运行,在页面发送到客户端之后。

几个选项:返回部分视图应该可以。您可以返回一个包含下拉列表的部分视图并从 ViewBag 中填充它。看起来像这样:

初始页面:

...
<div id="advProductsSection"></div>
...

您的 ajax 将调用相同的函数,但会返回部分视图:

public ActionResult GetAdvProdList(int prod_id) { // product id
...
ViewData["advproducts"] = new SelectList((IEnumerable<SelectListItem>)adv_list.ToList(), "Value", "Text");
return View("_AdvProducts");
}

然后是局部视图(这里命名为_AdvProducts.cshtml):

@Html.DropDownList("className", (IEnumerable<SelectListItem>) ViewBag["advproducts"])

您的 ajax 函数需要更改以将 div 替换为新的部分:

success: function (result) {
    $('#advProductsSection').html(result);
}

或类似的东西..

第二种选择是从 Action Method 返回 JSON 并用它填充下拉列表。

你的控制器:

...
return JSON(adv_list.ToList());
}

然后在你的 ajax 成功函数中:

success: function(list) {
    // states is your JSON array
    var $dropdown = $('#Dropdown');
    $.each(list, function(i, product) {
        $('<option>', {
            value: list.Value
        }).html(list.Text).appendTo($dropdown);
    });
}

prodchange调用时,您需要再次清除下拉列表。

于 2013-04-15T03:16:34.770 回答