2011-08-22 48 views
2

Javascript大师,我需要你的帮助。在JavaScript中比较两个数组的不同值

我需要比较两个不同的数组并检查不同的值。这些值来自相同形式的多选元素。我尝试获取当前值列表(cacheTermList)并检查更改的新值(newTermList)。这个想法是,如果输入新值,我想传递一个id给ajax调用,并将一些数据返回到屏幕。

代码:

var cachedTermList = $('select#edit-categories').val(); 

     if (cachedTermList == null) { 
     var cachedTermList = new Array(); 
     } 

     $('select#edit-categories').chosen().change(function() { 
     var newTermList = $('select#edit-categories').val(); 

     if (cachedTermList != null) { 
      for(var i = 0; i < newTermList.length; i++) { 
      alert(newTermList[i]); 
      if (!($.inArray(newTermList[i], cachedTermList))) { 
       $.ajax({ 
       type: "GET", 
       url: "/classifieds/js/term/" + newTermList[i], 
       success: function(data){ 
        //$('div#term-help-text').html(data); 
        cachedTermList.push(newTermList[i]); 
        alert(cachedTermList); 
       } 
       }); 
      } 
      } 
     } else { 

     } 
     }); 

熊我,我不倾向于过于频繁使用JavaScript工作。我试图通过在加载时设置cachedTermList来获取当前值列表,然后当select发生变化时,将newTermList设置为该字段的新值,然后对其进行循环,然后检查该列表中不存在的值缓存列表。

虽然我可以看到事情发生,并转储两个术语列表,并看到不同的值,但对于我的生活,我无法将它找到的值推到缓存列表中,以便下一次元素更改时,它不会一次又一次地向ajax调用发送相同的值。 .push()执行后,它只是添加没有值的',,,'。我哪里错了?

回答

0

您在for循环中使用ajax,并在其成功处理程序中推送newTermList项目。由于默认情况下ajax是异步的,所以循环不会等待ajax请求完成。尝试将推送代码放在ajax调用之外。但是,如果ajax调用失败,这将不起作用,可能是你不想在ajax调用失败时将该项添加到缓存中。

尝试这样的事情

for(var i = 0; i < newTermList.length; i++) { 
     alert(newTermList[i]); 
     if (!($.inArray(newTermList[i], cachedTermList))) { 
      $.ajax({ 
      type: "GET", 
      context: i,//Here I am setting the value of i into context which can be used in the success handler using this keyword 
      url: "/classifieds/js/term/" + newTermList[i], 
      success: function(data){ 
       //$('div#term-help-text').html(data); 
       cachedTermList.push(newTermList[this]); 
       alert(cachedTermList); 
      } 
      }); 
     } 
     } 
5

这是典型的开合 - 循环问题。所有success回调参考相同i。在执行回调时,循环已经完成并且i将具有值newTermList.length + 1,因此newTermList[i]将返回undefined

你必须通过引入一个新的范围来捕获索引或值,这可以通过调用一个函数来完成(JavaScript有没有块范围)。

更新:另一个问题是$.inArray不返回一个布尔值,但该元素或-1的索引。所以你必须将返回值与-1进行比较。

$('select#edit-categories').chosen().change(function() { 
    // ... 
    for(var i = 0; i < newTermList.length; i++) { 
     if ($.inArray(newTermList[i], cachedTermList) === -1) { 
      addTerm(newTermList[i], cachedTermList); 
     } 
    } 
    //... 
}); 


function addTerm(term, target) { 
    $.ajax({ 
     type: "GET", 
     url: "/classifieds/js/term/" + term, 
     success: function(data){ 
      //$('div#term-help-text').html(data); 
      target.push(term); 
      alert(target); 
     } 
    }); 
} 

另外请记住,所有的Ajax调用基本上都会同时执行。循环不会等到一个通话完成。如果您想一次执行一个呼叫,则可以使用jQuery's Deferred objects

+0

我明白了。我试过了,但ajax每次都调用相同的url(ID不会更改)。 – Kevin

+0

@凯文:你确定吗?你有没有使用最新版本?我有一个错误(将'value'而不是'newTermList [i]'传递给'addTerm')。你在说什么ID? –

+0

在其传递给函数的术语的URL中,它始终是术语列表中的第一个ID,并且是的,我用newTermList [i]替换了值。 – Kevin