2013-03-08 25 views
0

我是法国人,所以借口一些翻译错误......

我有一个代码,使用jQuery和Ajax调用,我不明白以下问题。

我有一张表,第一行。 在该行的末尾,有两个选项:有效和删除。 当你点击有效的图标时,出现一个加载图标,出现一个新行,附加到表中,加载图标消失,并显示删除图标。

当您点击删除图标时,它会删除该行。

所以我的问题......

在开始的时候,我实现了一个“的onclick =有效的()”和“的onclick =”上的图标删除()”直接。 但现在,我觉得更干净使用:

$('#valid'+i).click(function(){ 
    valid(i); 
}); 
$('#delete'+i).click(function(){ 
    delete(i); 
}); 

,问题出现:当你点击,例如在删除图标线3条,这是谁出现在4号线装载...

有代码

PHP/HTML

<?php 
    include_once 'functions_sandbox.php'; 
?> 
<html> 
    <head> 
     <script src="http://code.jquery.com/jquery-1.9.0.min.js" type="text/javascript"></script> 
    </head> 
    <body> 
    <script type="text/javascript"> 
     //Fonction qui charge les datepicker et les différentes options sur les champs 
     function reload_jquery(){ 
      $('input[type=text][id*=tags]').each(function() { 
       i = $(this).attr('num'); 
       $(this).css('border','thin blue solid'); 
       $('#valid'+i).click(function(){ 
        valid_temps(i); 
       }); 
       $('#delete'+i).click(function(){ 
        delete_temps(i); 
       });    
      });  
     } 
     function valid_temps(i){ 
      $('#loading'+i).show(); 
      $('#valid'+i).hide(); 
      var variables = 'mode=saisie_temps&j='+$('#j').val(); 
      $.ajax(
       { 
        // Define AJAX properties. 
        type: "POST", 
        url: "/dgi/ajax_sandbox.php", 
        data : variables, 
        dataType: "html", 
        timeout: 6000, 

        // Define the succss method. 
        success: function(data) 
        { 
         $('#data_retour').append(data); 
         $('#loading'+i).hide(); 
         $('#delete'+i).show();     
         $('#j').val(parseInt($('#j').val())+1); 
         reload_jquery(); 
        } 
       } 
      );  
     } 
     function delete_temps(i){ 
      $('#loading'+i).show(); 
      $('#delete'+i).hide(); 
      $("#confirm").dialog({ 
       resizable: false, 
       height:160, 
       width: 350, 
       modal: true, 
       buttons: { 
        "Oui": function() { 
         supp_temps(i); 
         $(this).dialog("close"); 
        }, 
        "Non": function() { 
         $('#loading'+i).hide(); 
         $('#delete'+i).show(); 
         $(this).dialog("close"); 
        } 
       } 
      }); 
     } 
     function supp_temps(i){ 
      $('#ligne'+i).hide('slow'); 
     } 

    $(function(){ 
     reload_jquery(); 
    }); 

    </script> 
    <table id="data_retour" class="module"> 
     <?php echo ligne_saisie_sandbox(0); ?> 
    </table> 
    <div style="display:none" id="confirm" title="Confirmation">Voulez-vous vraiment supprimer ce temps ?</div> 
    <label>Indice J : </label> 
    <input type="text" value="1" id="j" name="j" /> 
</body> 
</html> 

在 'functions_sandbox.php'

function ligne_saisie_sandbox($j){ 
    $retour = ' 
    <tr id="ligne'.$j.'"> 
     <td class="cellule _light"> 
      <label>Attraction'.$j.' : </label> 
      <input type="text" id="tags'.$j.'" num="'.$j.'" /> 

      <img src="/dgi/img/b_save.png" alt="Valid" title="Valider votre temps" title="Valider le temps" id="valid'.$j.'" style="margin-top:5px;float:right"> 
      <img src="/dgi/img/b_empty.png" alt="Supprimer" title="Supprimer votre temps" title="Supprimer le temps" id="delete'.$j.'" style="margin-top:5px;float:right;display:none"> 
      <img src="/dgi/img/ajax_clock_small.gif" alt="Load" id="loading'.$j.'" style="margin-top:5px;float:right;display:none;" /> 
     </td>   
    </tr>'; 
    return $retour; 
} 

和Ajax的在 “ajax_sandbox.php”

include_once 'functions_sandbox.php'; 
switch ($_POST['mode']) 
{ 
    case "saisie_temps": 
     $j = $_POST['j']; 
     $retour = ligne_saisie_sandbox($j); 
     echo $retour; 
    break; 
} 

小图像的 “ligne_saisie_sandbox” 功能来说明问题

回答

2

你的问题出现了,因为你离开了var在这条线:

i = $(this).attr('num'); 

通过不使用var,你做i一个全局变量,这使得i在你的回调(delete_temps(i);)都指向全球i,而不是当地的i

更改该行:

var i = $(this).attr('num'); 

,它应该工作。我也建议不要使用自定义属性。使用HTML5 data-属性:

<input type="text" id="tags'.$j.'" data-num="'.$j.'" /> 

,并使用.data()功能:

var i = $(this).data('num'); 
+0

完美!我将“var”添加到我的变量中,我使用了HTML5属性,并且它工作正常。 – 2013-03-08 10:21:56

0

你体验什么是JavaScript中一个常见的问题。这是一个关闭问题。你隐式地在这一行中声明一个名为i的变量。

i = $(this).attr('num'); 

因为它被隐式声明,所以它也是全局的。这将导致.each()的每次迭代使用相同的变量。

在你的情况下,你必须选择如何解决它。在JavaScript中的变量必须的功能范围,因为你永远不重写我的价值,你根本就明确地声明变量,像这样:

var i = $(this).attr('num'); 

它一般建议,明确声明变量,你其实可以有大多数JS引擎检查本作你如果你开始你这样的功能

function(){ 
    "use strict"; 
    //... 
} 

另一种选择是这种封闭问题的更一般的解决方案。 $('#valid'+ i).click(function(){valid_temps(i); }); $('#delete'+ i).click(function(){ delete_temps(i); });

,你可以把它改成

i = $(this).attr('num')  
(function(i){ 
    $('#valid'+i).click(function(){ 
     valid_temps(i); 
    }); 
    $('#delete'+i).click(function(){ 
     delete_temps(i); 
    }); 
})(i); 

不同的是,在你的代码,我没有计算,直到被调用的方法,让你在.each()最后一次迭代写入i的值。在上面的代码i in立即被评估。 当闭合问题的一个简单的例子,你面对你可以采取这段代码

var i,j, arr = []; 

for(i=0;i<10;i += 1){ 
    //creates a function that closes over i 
    arr[arr.length] = function(){console.log(i);} 
} 
for(j=0;j<10;j += 1){ 
    arr[j](); //They all output 9 to the console 
} 

改变第一循环的身体

arr[arr.length] = (function(k){function(){console.log(k);}})(i); 

结果在大多数人首先想到的行为这就是说,0..9被输出到控制台

在你的特殊情况下,简单地在本地声明i可能是两个选项中最具可读性的,但是知道如何避免关闭变量一般来说。