0

我花了几天的时间来解决我的问题,但我完全做不到。
我正在做的是为数据库创建一个搜索页面。我不确定搜索的详细程度,所以我使用 ajax/partial 视图来添加搜索条件(我的意思是尝试,因为这是不起作用的部分)。
我可能犯了一个愚蠢的错误,我不知道......
它在没有 ajax/partial 视图的情况下工作,但这并不能真正满足我项目的目的(不够详细)。
我的代码如下:

这就是我的 ajax 所谓的局部视图:

<script src="@Url.Content("~/Scripts/jScript1.js")" type="text/javascript"></script>

@using (Html.BeginForm())
{


@Ajax.ActionLink("Add search criteria",
              "AddSearch", new AjaxOptions
              {
                  UpdateTargetId = "search",
                  InsertionMode = InsertionMode.InsertAfter,
                  HttpMethod = "POST",
                  OnSuccess = "DBUpdate"
              })

<div id="search">

</div>


<input type="submit" value="Search" />
}

我的部分观点:

@model MvcApplication1.Models.search    


<div id="a">

 @Html.DropDownListFor(x => x.Table, Model.Tables, "-- Select Table --")
 @Html.DropDownListFor(x => x.Type, Enumerable.Empty<SelectListItem>(), "-- Select Type --")
 @Html.DropDownListFor(x => x.Name, Enumerable.Empty<SelectListItem>(), "-- Select Name --")
 @Html.EditorFor(x => x.less)
 @Html.EditorFor(x => x.equ)
 @Html.EditorFor(x => x.more)

</div>

和我的 js 文件:

function DBUpdate() {


$('#Table').change(function () {
    var selectedTable = $(this).val();
    if (selectedTable != null && selectedTable != '') {
        $.getJSON('@Url.Action("Types")', { Table: selectedTable }, function (types) {
            var typesSelect = $('#Type');
            typesSelect.empty();
            $.each(types, function (index, types) {
                typesSelect.append($('<option/>', {
                    value: types.value,
                    text: types.text
                }));
            });
        });
    }
});


$('#Type').change(function () {
    var selectedType = $(this).val();
    var selectedTable = $('#Table').val();
    if (selectedType != null && selectedType != '') {
        $.getJSON('@Url.Action("Names")', { Type: selectedType, Table: selectedTable }, function (names) {
            var namesSelect = $('#Name');
            namesSelect.empty();
            $.each(names, function (index, names) {
                namesSelect.append($('<option/>', {
                    value: names.value,
                    text: names.text
                }));
            });
        });
    }
});


}

在此先感谢您的所有帮助,
丹尼尔

4

2 回答 2

1

您的代码有几个问题:

  • 您正在尝试@Url.Action("Types")在单独的 javascript 文件中使用服务器端助手,这显然是不可能的。
  • 您正在使用 id 选择器,例如$('#Table')and$('#Type')但您可能有多个行,因此多个具有相同 id 的下拉列表 => 这些是错误的选择器 => 您不再知道您正在选择哪个元素。

因此,让我们开始解决这些问题。

首先我们从修改部分开始:

@model search    
<div>
    @Html.DropDownListFor(
        x => x.Table, 
        Model.Tables, 
        "-- Select Table --", 
        new { 
            id = Guid.NewGuid(),
            @class = "tables", 
            data_url = Url.Action("Types") 
        }
    )

    @Html.DropDownListFor(
        x => x.Type, 
        Enumerable.Empty<SelectListItem>(), 
        "-- Select Type --", 
        new { 
            id = Guid.NewGuid(),
            @class = "types",
            data_url = Url.Action("Names") 
        }
    )

    @Html.DropDownListFor(
        x => x.Name, 
        Enumerable.Empty<SelectListItem>(), 
        "-- Select Name --", 
        new { 
            id = Guid.NewGuid(),
            @class = "names" 
        }
    )

    @Html.EditorFor(x => x.less)
    @Html.EditorFor(x => x.equ)
    @Html.EditorFor(x => x.more)
</div>

请注意,我已将类属性应用于下拉列表,以便我可以更轻松地在我的 javascript 中选择它们。我还将一个 url 关联到前 2 个下拉列表,以便我们稍后可以将它们级联到相应的控制器操作。

说到级联,让我们写一个 jQuery 插件:

(function ($) {
    $.fn.cascade = function (options) {
        var defaults = { 
            additionalParameters: function() {
                return { };
            } 
        };
        var opts = $.extend(defaults, options);

        return this.each(function () {
            $(this).change(function () {
                var selectedValue = $(this).val();
                var params = opts.additionalParameters() || {};
                params[opts.paramName] = selectedValue;
                $.getJSON($(this).data('url'), params, function (items) {
                    opts.childSelect.empty();
                    $.each(items, function (index, item) {
                        opts.childSelect.append(
                            $('<option/>')
                                .attr('value', item.value)
                                .text(item.text)
                        );
                    });
                });
            });
        });
    };
})(jQuery);

有了这个插件,我们现在可以继续修改主视图:

@using (Html.BeginForm())
{
    @Html.ActionLink(
        "Add search criteria",
        "AddSearch",
        null,
        new { id = "add" }
    )
    <div id="search"></div>
    <input type="submit" value="Search" />
}

剩下的就是订阅锚的 click 事件(注意我使用的是 normalHtml.ActionLink而不是 an Ajax.ActionLink)并附加我们的插件:

$(function () {
    $('#add').click(function () {
        $.post(this.href, function (result) {
            var $result = $(result);
            $('#search').append($result);
            var tablesSelect = $('.tables', $result);
            var typesSelect = $('.types', $result);

            tablesSelect.cascade({
                paramName: 'table',
                childSelect: $('.types', $result)
            });
            typesSelect.cascade({
                paramName: 'type',
                additionalParameters: function () {
                    return { table: tablesSelect.val() };
                },
                childSelect: $('.names', $result)
            });
        });
        return false;
    });
});

所有这些都可以发生在一个单独的 javascript 文件中。这显然假设我们有 2 个相应的控制器操作,它们将返回级联下拉列表的 JSON 值。

以下只是模拟,以便您可以看到输入/输出是什么。您当然会用更现实的东西替换虚拟值:

public ActionResult Types(string table)
{
    var model = Enumerable.Range(1, 5).Select(x => new
    {
        value = x,
        text = "type " + x
    });
    return Json(model, JsonRequestBehavior.AllowGet);
}

public ActionResult Names(string type, string table)
{
    var model = Enumerable.Range(1, 2).Select(x => new
    {
        value = x,
        text = "name " + x
    });
    return Json(model, JsonRequestBehavior.AllowGet);
}
于 2012-04-10T20:22:57.000 回答
0

尝试将您的change函数包装在 document.ready()

$.document.ready(function () {
    $('#Table').change(function () {
     .....

    $('#Type').change(function () {
     ....
});

如果您不这样做,则更改事件可能会绑定到页面上尚不存在的元素 - 这意味着它永远不会被绑定。

编辑

尝试将此添加到主视图

<script src="@Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/MicrosoftMvcAjax.js")" type="text/javascript"></script>
于 2012-04-10T16:00:06.377 回答