2013-03-08 56 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可能是兩個選項中最具可讀性的,但是知道如何避免關閉變量一般來說。