【问题标题】:Pass variable to getJSON jQuery function from closure scope将变量从闭包范围传递给 getJSON jQuery 函数
【发布时间】:2012-10-19 07:40:57
【问题描述】:

我正在尝试将相同的 jQueryJSON ASP.NET MVC3 方法 附加到两个不同的 <select> 元素:

<select id="StartYear">
<option value="">Select Year</option>
<option value="2000">2000</option>
<option value="2001">2001</option>
</select>

<select id="StartMonth">
<option value="">Select Month</option>
</select>

同样适用于 ID 为 "EndYear""EndMonth"&lt;select&gt; 元素。

我想将相同的 jQuery 函数附加到“开始年份”和“结束年份”:

$('[id$="Year"]').change(function () {
        var selectedYear = $(this).val();
        var selectedId = $(this).attr('id')
        if (selectedYear != null && selectedYear != '') {
            $.getJSON('@Url.Action("Months")', { year: selectedYear }, function (months) {
                var monthsSelect = $('#StartMonth');
                if (selectedId == 'EndYear') {
                    monthsSelect = $('#EndMonth');
                }
                monthsSelect.empty();
                daysSelect.prepend("<option text='-- select month --' value='' selected='selected'></option>");
                $.each(months, function (index, month) {
                    monthsSelect.append($('<option/>', {
                        value: month.value,
                        text: month.text
                    }));
                });
            });
        }
    });

但是,此代码不起作用。我用 Bugzilla 对其进行了调试,发现这种情况 (selectedId == 'EndYear') 破坏了该功能。变量 selectedId 在闭包范围内,但我不知道如何将其带入函数范围内。否则我不知道这是什么原因。 请记住,如果没有这种情况,代码可以正常工作(当然只是使用#StartMonth)

【问题讨论】:

  • 它是怎么破的?有没有报错?
  • getJSON 方法之外的 selectedId 是什么? (所以,分配后console.log($(this).attr('id'));?)
  • 谢谢!在它给 StartDate 然后 undefined

标签: jquery json scope


【解决方案1】:

如果我正确理解您的问题,则可以在 $.getJSON 的成功处理程序内部访问变量 selectedId,但变量的值可能已经被另一个 change 事件更改。

例如,如果两个change 事件将在例如“#EndYear”和“#StartYear”的短时间间隔内声明,则可能如下

  1. 将触发“#EndYear”的change 事件
  2. selectedId 变量将设置为“EndYear”
  3. 将启动第一个$.getJSON
  4. change 将触发“#StartYear”事件
  5. selectedId 变量将设置为“StartYear”
  6. 第二个$.getJSON将被启动
  7. 第一个 $.getJSON 将完成,selectedId 变量的值将是 success 处理程序内的“StartYear”
  8. 第二个$.getJSON 将完成,selectedId 变量的值将是success 处理程序内的“StartYear”

所以我认为您只需要不同的实例 selectedId 变量来使用$.getJSON 发生之前的值。您可以以不同的方式实现它。将$.getJSON 替换为$.ajax 并使用$.ajaxcontext 参数对我来说似乎是最自然的。代码可能如下

$('[id$="Year"]').change(function () {
    var selectedYear = $(this).val();
    var selectedId = $(this).attr('id')
    if (selectedYear != null && selectedYear != '') {
        //$.getJSON('@Url.Action("Months")', {year: selectedYear}, function(months){
        $.ajax({
            url: '@Url.Action("Months")',
            dataType: 'json',
            data: { year: selectedYear },
            context: {selectedId: selectedId},
            success: function (months) {
                var selectedId = this.selectedId; // get from context
                ....
            }
        });
    }
});

【讨论】:

  • 感谢奥列格,我的问题容易多了。我不明白为什么 $.getJSON 之前的 selectedId 等于“StartDate”或“EndDate”并且函数内部未定义
  • @CiccioMiami:不客气!无论如何,我建议将 selectedId 的值保存在 new object 中,您将在 success 回调中访问它。在这种情况下,您将确保在 success 回调中保持 selectedId 的值不变。
  • @CiccioMiami:我有另一个想法可能是您的问题的原因:the event bubbling 或基于它的一些效果。如果您在元素上注册 change 事件,那么 children 的所有更改都将遵循 change 事件处理程序的调用。因此,您可能对selectedId 进行更多更改。我建议您在事件处理程序中包含console.log 并分析结果。您可能会看到selectedId 变量何时重置为undefined(当$(this).attr('id') 返回undefined 时)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-02
  • 2011-01-18
  • 1970-01-01
  • 2014-12-05
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
相关资源
最近更新 更多