【问题标题】:Delayed execution of Javascript延迟执行 Javascript
【发布时间】:2018-02-25 00:00:40
【问题描述】:

在我的项目中,我有一个 modal 窗口,其中显示了一个类 (Machine) 的两个属性 (Family, TypeID) 的级联下拉列表。

问题: 仅当模态窗口第二次打开时,才会填充相关下拉列表。第一次,什么都没有发生:

下面是它的工作原理图,以便更好地理解:

请注意,显示 Modelo(Modelo 是 TypeID 的名称)的行一开始是空的,但一旦重新打开,它就会填充预期的信息。

代码:

注意 Javascript 位于索引页面中,其中包含指向模式窗口的链接

在创建或编辑新的Machine 时使用此模式窗口。 出于这个原因,在 Javascript 的第一部分中,我检查我所处的情况并检查 Machine 属性:MchName 是否具有值。 如果它没有值,我将变量items 的值分配给属性TypeID,该属性应在Modal 打开时显示。

@section scripts{
<script src="~/js/machine-index.js" asp-append-version="true"></script>


<script type="text/javascript">
    $(document).ready(function () {
        $('#FamilyID').change(function () {
            var url = '@Url.Content("~/")' + "Machines/GetModel";
            var ddlsource = "#FamilyID";
            $.getJSON(url, { FamilyID: $(ddlsource).val() }, function (data) {
                var items = '';
                $("#TypeID").empty();
                $.each(data, function (i, model) {
                    items += "<option value='" + model.value + "'>" + model.text + "</option>";
                });
                $('#TypeID').html(items);
            });
        });
        $('#modal-action-machine').on('shown.bs.modal', function () {
            var test = "#MchName";
            if ($(test).val()) {

            } else {
                var items = "<option value='0'>-- Seleccione Modelo --</option>";
                $('#TypeID').html(items);
            }
        });
    });
</script>
<script type="text/javascript">
    $(function () {
        $('.datepicker').datepicker({
            "autoclose": true,
            format: 'dd/mm/yyyy'
        }).datepicker("setDate", new Date());
    });
</script>
<script src="~/lib/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
}

获取方法:

    [HttpGet]
    public IActionResult CreateEdit(int? id)
    {
        //Lista de Familias
        List<MachineFamily> FamilyList = new List<MachineFamily>();
        FamilyList = (from family in _context.MachineFamilies
                      select family).ToList();
        FamilyList.Insert(0, new MachineFamily { FamilyID = 0, FamilyDescription = "-- Seleccione Familia --" });
        ViewBag.ListofFamily = FamilyList;

        ViewBag.TypeID = string.Empty;
        return PartialView("~/Views/Shared/Machines/_Create.cshtml");
    }

JsonResult:

    public JsonResult GetModel(int FamilyID)
    {
        List<MachineType> ListaModelos = new List<MachineType>();
        ListaModelos = (from model in _context.MachineTypes
                        where model.FamilyID == FamilyID
                        select model).ToList();
        ListaModelos.Insert(0, new MachineType { TypeID = 0, TypeDescription = "-- Seleccione Modelo --" });
        return Json(new SelectList(ListaModelos, "TypeID", "TypeDescription"));
    }

视图:模态

@model Application.Models.ApplicationviewModels.MachineIndexData
@using Application.Models

<form asp-action="CreateEdit" role="form">
    @await Html.PartialAsync("_ModalHeader", new ModalHeader
{ Heading = String.Format("Actualización de Modelo") })

    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
    <div class="modal-body form-horizontal">
        <input type="hidden" asp-for="Id" />
        <div class="form-group">
            <label asp-for="FamilyID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="FamilyID" class="form-control"
                        asp-items="@(new SelectList(ViewBag.ListofFamily,"FamilyID","FamilyDescription"))"></select>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="TypeID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="TypeID" class="form-control"
                        asp-items="@(new SelectList(ViewBag.TypeID,"TypeID","TypeDescription"))"></select>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="BrandID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="BrandID" class="form-control" asp-items="ViewBag.BrandID">
                    <option value="">-- Seleccione Marca --</option>
                </select>
                <span asp-validation-for="BrandID" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="SupplierID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="SupplierID" class="form-control" asp-items="ViewBag.SupplierID">
                    <option value="">-- Seleccione Proveedor --</option>
                </select>
                <span asp-validation-for="SupplierID" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="StoreID" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select asp-for="StoreID" class="form-control" asp-items="ViewBag.StoreID">
                    <option value="">-- Seleccione Tienda --</option>
                </select>
                <span asp-validation-for="StoreID" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="MchName" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="MchName" class="form-control" />
                <span asp-validation-for="MchName" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="NumDevices" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input id="NumDevices" asp-for="NumDevices" class="form-control" readonly />
                <span asp-validation-for="NumDevices"  class="text-danger"></span>
                <input id="getNum" type="range" min="" max="10" step="1" onchange="fetch()" class="form-control" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="FechaCompra" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input data-format="0:dd/MM/yyyy" type="datetime" asp-for="FechaCompra" class="form-control datepicker" />
                <span asp-validation-for="FechaCompra" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="CostoMaq" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="CostoMaq" class="form-control" />
                <span asp-validation-for="CostoMaq" class="text-danger"></span>
            </div>
        </div>
        <div class="form-group">
            <label asp-for="MachineStatus" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <select name="MachineStatus" asp-for="MachineStatus" class="form-control" disabled>
                    <option value="0">Operativo</option>
                    <option value="1" selected="selected">Nuevo Item</option>
                    <option value="2">Reparación</option>
                </select>
                <input type="hidden" name="MachineStatus" value="1" />
                <span asp-validation-for="MachineStatus" class="text-danger"></span>
            </div>
        </div>

        @await Html.PartialAsync("_ModalFooter", new ModalFooter { })
    </div>
</form>

最后说明:我认为要解决此问题,我应该更改 Javascript。有人可以向我解释为什么会发生这种情况以及如何解决吗?

更新:尝试为“MchName”字段分配一个新 id 并将其发送到脚本

查看:

    <div class="form-group">
        <label asp-for="MchName" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input id="MchName2" asp-for="MchName" class="form-control" />
            <span asp-validation-for="MchName" class="text-danger"></span>
        </div>
    </div>

脚本:

        $('#modal-action-machine').on('shown.bs.modal', function () {
            var test = document.getElementById("MchName2").value;
            if (test) {

            } else {
                var items = "<option value='0'>-- Seleccione Modelo --</option>";
                $('#TypeID').html(items);
            }
        });

运气不好。

更新:第二次尝试

查看:

    <div class="form-group">
        <label asp-for="MchName" class="col-md-2 control-label"></label>
        <div class="col-md-10" id="MchName2">
            <input asp-for="MchName" class="form-control" />
            <span asp-validation-for="MchName" class="text-danger"></span>
        </div>
    </div>

脚本:

        $('#modal-action-machine').on('shown.bs.modal', function () {
            var test = "#MchName2 #MchName";
            if ($(test).val()) {

            } else {
                var items = "<option value='0'>-- Seleccione Modelo --</option>";
                $('#TypeID').html(items);
            }
        });

【问题讨论】:

  • 在第一个shown.bs.modal 事件中,您正在定义一个change 事件处理程序...它不会执行,它只是被定义。然后,可能在下一个 shown.bs.modal 之前发生了一个 change 事件......所以你会看到下拉列表。
  • @LouysPatriceBessette 该更改事件适用于第一个下拉列表更改(FamilyID)时,因此第二个相应更新。在此之前的一个步骤是在窗口第二次打开时执行的“shown.bs.modal”脚本。它不应该在第一次打开时起作用吗?
  • 您应该创建一个 CodePen 来重现该问题。
  • 我不知道那是什么。是时候谷歌了~
  • @LuisAlbertoDelgadodelaFlo,在我的回答中,我给了你一些真正的建议,但你的错误可能来自另一个 javascript 函数。请发布您的整个 javascript 部分。

标签: javascript c# jquery asp.net ajax


【解决方案1】:

我找到了适用于这种特定情况的答案。

错误的第一件事是评估未在ifstatement 中定义的变量。

$('#modal-action-machine').on('shown.bs.modal', function () {
    var test = "#MchName";
    if ($(test).val()) {

在这段代码中,我将#MchName 的值分配给test,但是在第一次打开模式之前,#MchName 没有被定义,为此,不执行其余的代码。

第二个:转身是使用Create按钮的点击事件来识别我是新机还是更新。

为此,我将声明一个全局变量并将其赋值为零。 如果单击“创建”按钮,则为该变量分配值 1,如果为真,则为 #TypeID 变量分配默认值。

模态关闭后,将全局变量重新赋值为零。这适用于点击另一个按钮(更新)来调用模态的情况。

这是代码:

var global = this;
var wasclicked = 0;

$(document).ready(function () {

    document.getElementById("modalbutton").onclick = function () {
        global.wasclicked = 1;
    };

    $('#modal-action-machine').on('hidden.bs.modal', function () {
        global.wasclicked = 0;
    });

    $('#modal-action-machine').on('shown.bs.modal', function () {
        if (global.wasclicked == 1) {
            var items = "<option value='0'>-- Seleccione Modelo --</option>";
            $('#TypeID').html(items);
        }

    });

这样,项目按预期工作。

感谢您的帮助!

【讨论】:

    【解决方案2】:

    您应该将两个 shown.bs.modal 事件处理程序包装在一个 document.ready 函数中。

    每次触发shown.bs.modal 事件时,它都会将change 事件处理程序绑定到您的select 元素。你应该只bind一次。

    script type="text/javascript">
    $(document).ready(function () {
        $('#FamilyID').change(function () {
            var url = '@Url.Content("~/")' + "Machines/GetModel";
            var ddlsource = "#FamilyID";
            $.getJSON(url, { FamilyID: $(ddlsource).val() }, function (data) {
                var items = '';
                $("#TypeID").empty();
                $.each(data, function (i, model) {
                    items += "<option value='" + model.value + "'>" + model.text + "</option>";
                });
                $('#TypeID').html(items);
            });
        });
        $('#modal-action-machine').on('shown.bs.modal', function () {
            var test = "#MchName";
            if ($(test).val()) {
    
            } else {
                var items = "<option value='0'>Select</option>";
                $('#TypeID').html(items);
            }
        });
    });
    

    【讨论】:

    • 您的回答是正确的,但您是否也可以考虑利用 ajax 异步调用的 success 参数?
    • @AlexanderDixon,异步方法只有在他改变了第一个选择元素时才会执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2011-09-23
    相关资源
    最近更新 更多