Jquery 定时问题设置文档就绪处理程序中选定的dropdownlist项

Jquery 定时问题设置文档就绪处理程序中选定的dropdownlist项,jquery,asp.net-mvc,asp.net-mvc-3,Jquery,Asp.net Mvc,Asp.net Mvc 3,背景故事:我正在开发我的第一个ASP.NET MVC 3应用程序,希望为客户提供两个类似的页面—创建和编辑。 两个页面都有两个下拉列表选择器,允许客户首先选择一种锥形或碟形,然后选择一个子类型 根据第一种选择(例如,客户选择“华夫饼圆锥体”,然后显示子类型,如“巧克力蘸汁”, “普通”等) 我在ConeDish选择器上键入“change”事件,以调用控制器操作以返回相关子类型。大概是这样的: 查看 <td>@Html.DropDownListFor(model => model

背景故事:我正在开发我的第一个ASP.NET MVC 3应用程序,希望为客户提供两个类似的页面—创建和编辑。 两个页面都有两个下拉列表选择器,允许客户首先选择一种锥形或碟形,然后选择一个子类型 根据第一种选择(例如,客户选择“华夫饼圆锥体”,然后显示子类型,如“巧克力蘸汁”, “普通”等)

我在
ConeDish
选择器上键入“change”事件,以调用控制器操作以返回相关子类型。大概是这样的:

查看

<td>@Html.DropDownListFor(model => model.TypeID, new SelectList(Model.ConeDishTypes, "TypeID", "Name"), "-- Select Cone or Dish --", new { @id = "conedishselector" })
</td>
<td>@Html.DropDownListFor(model => model.SubtypeID, Enumerable.Empty<SelectListItem>(), "-- How Big? --", new { @id = "subtypeselector" })
</td>
事情会成功的,但我认为这充其量只是一个管道胶带解决问题的办法


解决方案:

因此,我相信这一切都归结为一个事实,
getJSON
是一个异步调用(),这在文档中是清楚的,因为它有一个success回调,如果请求成功,它将在将来的某个时间执行。那是什么意思?这意味着通过documentready函数,调用
$('#yourfortiteselector').trigger(“change”)
然后立即转身并期望
getJSON
的结果完成是有缺陷的逻辑。正如我在上面通过
setTimeout
所做的那样,等待是一种黑客行为,会导致问题的次优“解决方案”。它依赖于(糟糕的是,我可能会补充)成功回调在等待500毫秒或指定的任何时间后都会完成它的工作的概念

我将职能重组为:

<script type="text/javascript">
    $(document).ready(function () {
        $('#conedishselector').change(function () {
            var selectedTypeID = $(this).val();
            if (selectedTypeID != null) {
                $.getJSON('@Url.Action("SubtypesForType")', { typeID: selectedTypeID }, function (subtypes) {
                    var subtypesSelect = $('#subtypeselector');
                    subtypesSelect.empty();
                    subtypesSelect.append($('<option/>', { value: 0, text: '-- How Big? --' }));
                    $.each(subtypes, function (index, subtype) {
                        subtypesSelect.append($('<option/>', {
                            value: subtype.SubtypeID,
                            text: subtype.Name
                        }));
                    });
                    var theVal = $("#hiddensubtypeid").val();
                    if (theVal != null && theVal != "") {
                       $('#subtypeselector').val(theVal);
                    }
                });
            }
        });

        $('#conedishselector').trigger("change");
    });
</script>

$(文档).ready(函数(){
$('#conedishselector')。更改(函数(){
var selectedTypeID=$(this.val();
如果(selectedTypeID!=null){
$.getJSON('@Url.Action(“subjectsfortype”),{typeID:selectedTypeID},函数(子类型){
变量子类型选择器=$(“#子类型选择器”);
子类型select.empty();
subsubselect.append($('',{value:0,text:'--多大?--'}));
$.each(子类型,函数(索引,子类型){
子类型选择。附加($(''){
值:subtype.subscriptid,
文本:子类型。名称
}));
});
var theVal=$(“#hiddensubiteid”).val();
如果(theVal!=null&&theVal!=“”){
$('#选择器').val(theVal);
}
});
}
});
$('conedishselector')。触发器(“更改”);
});
而且,正如Badger所建议的,选择作为成功回调的一部分,这确保了子类型已填充

这样做的好处还在于,用户可以将第一个DropDownList的选择更改为某个新值(例如,如果她想查看我们提供的其他锥形杯/盘子),然后再次将其设置回原始值。当这种情况发生时,隐藏字段仍然保存原始主类型附带的原始子类型,回调代码相应地重置子类型DropDownList。因此,用户不必为重新选择盘子大小或华夫饼蛋卷类型而烦恼。我认为,这只是对用户的一点额外尊重,也是解决方案的一个很好的副作用


因此,这是一个“解决方案”,也许不是最好的解决方案,但我想说明它的完整性。

我认为您的问题确实是时间问题。您正在发送数据请求,然后在不等待JSON响应的情况下尝试设置所选项目

除非有特别的理由不这样做,否则我将以不同的方式实现getJSON success函数

成功加载子类型时,可以检查其中一个是否为HiddenSubiteID。如果是,则选择它,如果不是,则保留默认值


如果需要,您可以在成功功能“使用”HiddenSubiteID时清除它,尽管从用户体验来看,如果用户选择了相关的主类型,总是跳转到当前选定的项目可能是有意义的。

我认为您的问题确实是计时。您正在发送数据请求,然后在不等待JSON响应的情况下尝试设置所选项目

除非有特别的理由不这样做,否则我将以不同的方式实现getJSON success函数

成功加载子类型时,可以检查其中一个是否为HiddenSubiteID。如果是,则选择它,如果不是,则保留默认值


如果需要,您可以在成功函数“使用”HiddenSubiteId时清除它,尽管根据您的用户体验,如果用户选择了相关的主类型,总是跳转到当前选择的项目可能是有意义的。

让我重申一下您写的内容,看看我是否遵循。因此,当我遍历子类型时,我会检查其中一个是否与HiddenSubiteId匹配,然后选择它,然后清除HiddenSubiteId,以便后续对getJSON的调用(即,当用户选择不同的主类型时)不会选择子类型。我想我可以关闭原始主类型和子类型的键,这样如果选择了原始主类型,它就可以重新选择原始子类型。这基本上就是你说的吗?(顺便说一句,谢谢你的回复)。是的。或者填充子类型,然后按照代码目前尝试的方式设置所选值(来自隐藏值)。无论哪种方式,都要处理是否将所选值设置为成功函数的一部分,而不是在文档准备中。请让我重述一下你写的内容,看看我是否听懂了。因此,当我遍历子类型时,我会检查其中一个是否与HiddenSubiteId匹配,然后选择
public ActionResult SubtypesForType(int typeID)
{
    using (var db = new IceCreamEntities())
    {
        IEnumerable<Subtypes> subtypes = db.Subtypes.Where(m => m.TypeID == typeID).ToList();
        List<SubtypeIdentifierViewModel> subtypeVMs = new List<SubtypeIdentifierViewModel>();
        foreach (var subtype in subtypes)
        {
            subtypeVMs.Add(new SubtypeIdentifierViewModel(subtype.SubtypeID, subtype.Name, subtype.Size));
        }
        return Json(subtypeVMs, JsonRequestBehavior.AllowGet);
    }
}
<script type="text/javascript">
    $(document).ready(function () {
        $('#conedishselector').change(function () {
            var selectedTypeID = $(this).val();
            if (selectedTypeID != null) {
                $.getJSON('@Url.Action("SubtypesForType")', { typeID: selectedTypeID }, function (subtypes) {
                    var subtypesSelect = $('#subtypeselector');
                    subtypesSelect.empty();
                    subtypesSelect.append($('<option/>', { value: 0, text: '-- How Big? --' }));
                    $.each(subtypes, function (index, subtype) {
                        subtypesSelect.append($('<option/>', {
                            value: subtype.SubtypeID,
                            text: subtype.Name
                        }));
                    });
                });
            }
        });

        $('#conedishselector').trigger("change");

        var theVal = $("#hiddensubtypeid").val();
        $("#debug").val(theVal);
        if (theVal != null && theVal != "") {
            // alert here just to check
            alert("I got here.");
            $('#subtypeselector').val(theVal);
            // I also tried this, but that didn't work without the alert either - didn't think it would though 
            //            $("#subtypeselector option[value=" + val + "]").attr("selected", "selected");
        }
    });
</script>       
$('#conedishselector').trigger("change");
$(function($) {
    setTimeout(function() {       
        var theVal = $("#hiddensubtypeid").val();
        $("#debug").val(theVal);
        if (theVal != null && theVal != "") {
            // alert here just to check
            alert("I got here.");
            $('#subtypeselector').val(theVal);
        }
    }, 200); // or 500, or 1000
});
<script type="text/javascript">
    $(document).ready(function () {
        $('#conedishselector').change(function () {
            var selectedTypeID = $(this).val();
            if (selectedTypeID != null) {
                $.getJSON('@Url.Action("SubtypesForType")', { typeID: selectedTypeID }, function (subtypes) {
                    var subtypesSelect = $('#subtypeselector');
                    subtypesSelect.empty();
                    subtypesSelect.append($('<option/>', { value: 0, text: '-- How Big? --' }));
                    $.each(subtypes, function (index, subtype) {
                        subtypesSelect.append($('<option/>', {
                            value: subtype.SubtypeID,
                            text: subtype.Name
                        }));
                    });
                    var theVal = $("#hiddensubtypeid").val();
                    if (theVal != null && theVal != "") {
                       $('#subtypeselector').val(theVal);
                    }
                });
            }
        });

        $('#conedishselector').trigger("change");
    });
</script>