【问题标题】:Javascript Array Losing an Element At RandomJavascript 数组随机丢失一个元素
【发布时间】:2012-08-08 16:39:43
【问题描述】:

我遇到了一个非常奇怪的问题。我在我的一个站点上使用来自 JQueryUI 的 jsTree,并且我在不同的 .js 文件中使用了不同的实现。其中一个似乎可以工作,这非常令人困惑,因为它使用几乎相同的代码(只有变量名称不同)到被破坏的实现。问题来自上下文菜单功能。我使用的代码如下:

$(document).ready(function () {
    if(typeof dryerList == 'undefined' || dryerList.length == 0) {
        var dryerList = [];
        $.ajax({
            url:'../TrackingApp/getGrainBins.php?t=234.23423452353',
            async: false,
            success: function(text) {
                try {
                    dryerList = $.parseJSON(text);
                } catch (e) {
                    alert('ERROR: ' + e);
                }

                if(dryerList.length == 0) {
                    alert('ERROR: No fleet data received.')
                }
            }
        });
    }

    $("#dryerListTree").jstree({
        plugins : ['json_data', 'ui', 'themes', 'contextmenu'],
        contextmenu: {items: customBinMenu},
        json_data : { data: binNodes }
    });

    $('#dryerListTree').bind("dblclick.jstree", function (event) {
        var node = $(event.target).closest("li");
        var id = node[0].id;

        for(i=0; i < dryerList.length; i++) {
            if(id == dryerList[i].id) {
                centerMap(dryerList[i].y, dryerList[i].x);
                break;
            }
        }
    });
});


function customBinMenu(node) {
    if ($(node).hasClass("folder")) {
        return;
    }

    var items = {
        centerItem: {
            label: "Locate",
            action: function () {
                // Centers map on selected bin
                var id = node[0].id;

                for(i=0; i < dryerList.length; i++) {
                    if(id == dryerList[i].id) {
                        centerMap(dryerList[i].y, dryerList[i].x);
                        break;
                    }
                }
            }
        },
        dashboardItem: {
            label: "Dashboard",
            action: function () {
                // Opens dryer info window over map
                var id = node[0].id;
                var dryerIndex = -1;

                for(i=0; i < dryerList.length; i++) {
                    if(id == dryerList[i].id) {
                        dryerIndex = i;
                        break;
                    }
                }
            }
        }
    };

return items;
}

奇怪的是,双击处理程序工作得很好。当我到达 customBinMenu() 函数时,dryerList 数组就在那里,并且dryerList[0] 包含它应该包含的 5 个值中的 4 个 - 但不知何故,“id”元素已从该对象中删除。我已经研究了很长时间,但我无法弄清楚它如何在不丢失任何其他数据的情况下从对象中删除单个元素,尤其是当相同的代码适用于类似的列表时。有什么建议吗?

【问题讨论】:

  • 您在三个地方使用了全局变量“i”。你真的需要非常小心地在 JavaScript 中使用 var 声明你的局部变量。
  • 我在多个地方使用它,但只是按顺序使用 - 每次使用时都会重置该变量,并且在重置之前不会再次使用。
  • 我同意这可能不是问题,但这是一种冒险的不必要的做法。
  • 那么你是说我应该为代码中的每个 for 循环使用唯一的迭代器?
  • 如果您知道自己在做什么,据我所知,没有理由不重用 i 来计算您的迭代次数。只是不要嵌套它们!但是,您可能还想认真优化您的循环。不要在每次迭代时都得到dryerList.length!!!也做反向循环: i=dryerList.length; while(i--){//actions} 尽可能!

标签: javascript jquery-ui jstree


【解决方案1】:

好的,我在您的问题中读到:'and dryList[0] 包含它应该包含的 5 个值中的 4 个 - 但不知何故,'id' 元素已从该对象中删除'
所以 'element''value' 我假设你的意思是“属性”:准确地说是节点的“id”属性??

我在您的代码中看到:var id = node[0].id;

应该是:var id = node[0].getAttribute("id");

祝你好运!

更新 1:
好的,如果(根据您的评论)var id = node[0].id;(从节点 [0] 获取 id)没问题,那么 if(id == dryerList[i].id) 看起来是错误的,因为您只是(重新)将 id 定义为节点 [0] 的值身份证。
实际上,我不会使用 'id' 作为 var-name(在这种情况下)。

如果你这样做了怎么办:var idc = node[0].getAttribute("id");
然后:if(idc === dryerList[i].getAttribute("id"))

UPDATE 5:顺便说一句,您仍然有一些错误:

  • 您忘记使用分号来关闭警报:
    if(dryerList.length == 0) { alert('ERROR: No fleet data received.') }
  • 您应该在第 2 行和第 14 行使用 '===' 与 '0' 进行比较
  • 在现实生活中,您自然会在将函数 customBinMenu(node) 用于您的 document.ready 函数之前定义它。
    通过交换代码顺序修复。
  • 此 document.ready 函数也是如此,您在定义之前使用了 var dryList。
    修复者:var dryerList = dryerList || []; if(dryerList.length === 0){//ajax &amp; json code}

您能否确认this fiddle,它现在是有效的javascript,代表您的预期基线代码,它仍然会导致您的在dryerList 的节点集合中“id”属性为“未定义”的问题(因为您发布的代码包含一些在此jsfiddle 中修复的简单错误,不包括更新 1 中提到的内容,因为你评论说这不是问题)?

请问(既然您从 document.ready 开始),您为什么(仍然)检查dryerList 是否已经存在?
请问您是否可以用一些演示数据更新更正的小提琴供我们玩弄?

【讨论】:

  • 嗯,它看起来应该,但是不,node[0].id 值是正确的,因为我已经多次提醒它,它准确地显示了它应该的值,所以这不是问题。
  • 那么它什么时候删除id?也许一个 jsfiddle 会有助于追踪这个。
  • 这是一个想法,但是将 id 定义为 node[0].id 不应该影响dryerList[i].id - 两者应该完全分开。如果是这种情况,dryerList[i].id 将返回 node[0].id 的值,但因为它坐在那里,我得到了 undefined。
  • 你试过我的解决方案了吗?假设 node[0].id 给出了文本字符串“foobar”。然后将其存储到本地 var id。然后你有效地调用dryerList[i].foobar,它不存在因此给出'未定义'。到目前为止对我来说很有意义..但我可能弄错了。
  • 好吧,我试一试——我没想到会这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-27
  • 2013-11-14
  • 2014-07-23
  • 1970-01-01
相关资源
最近更新 更多