.each()函数中的$ .extend(),奇怪的行为?

时间:2012-01-10 00:32:54

标签: jquery json jquery-plugins

这是我的插件的结尾,作为Highcharts api的包装。我在extend()函数中使用each()将属性chart.renderTo设置为当前对象id属性。

这不起作用。 console.log($(this).attr('id'))的输出正确,但console.log(opt.chartOptions)仅将最后一个ID( chart2 )显示为chart.renderTo属性。

我错过了$.extend() jQuery函数吗?

    var chartOptions = {}; // Plain option object

    return this.each(function() { // Each div

        console.log($(this).attr('id')); // Output: "chart1", "chart2"
        $.extend(opt.chartOptions, { chart : {renderTo : $(this).attr('id') } });
        console.log(opt.chartOptions); // Ops! chart.renderTo is always "chart2"

        $.ajax({
            url : opt.url,
            type : 'POST',
            data : opt.data,
            dataType : 'json',
            success : function(data) {
                $.extend(data, opt.chartOptions); // Merge data from server
                new Highcharts.Chart(data);
            }
        });

    });

1 个答案:

答案 0 :(得分:0)

我假设opt.chartOptions是一个在插件函数中本地作用的变量。如果这是真的,那么你在这里做的是尝试为包装器上下文中的每个opt.chartOptions扩展div

每当您在扩展中进行迭代时(例如$.extend(foo,bar)),jQuery都会使用foo的属性扩展bar。我相信你已经意识到了这一点。

您可能遗漏的是,在您的情况下,bar始终是{ chart : {} }形式的对象。长话短说,.each()的每次迭代都会覆盖之前的$.extend()来电。

通过第一次迭代,opts.chartOptions将使用opts.chartOptions.chart进行扩展,该div是根据.each()上下文中的第一个opts.chartOptions计算的。

通过第二次迭代,您将尝试再次使用opts.chartOptions.chart已经拥有来再扩展div。但是jQuery并不关心,所以它会将第二个div的计算值分配给opts.chartOptions.chart中的第一个opts.chartOptions值。

等等,等等。

虽然你在这里使用它的方式,通常应该无关紧要,但这是因为你在AJAX的回调函数中使用了opts.chartOptions的值。这会在.each()上创建一个闭包,这意味着当你的AJAX回调触发时,它的值可能不是你所期望的(因为它可能已被另一次迭代修改) {{1}},等等等等。

<强>呼!!