2011-09-12 13 views
0

alertにはなぜundefと表示されますか?Javascript:可変範囲に関する質問

#!/usr/bin/env perl 
use warnings; 
use 5.014; 
use utf8; 
use Mojolicious::Lite; 
use DBI; 

my $db = 'my_test_db.db'; 
my $table = 'my_test_table'; 
my $dbh = DBI->connect("dbi:SQLite:dbname=$db", '', '', 
      { RaiseError => 1, PrintError => 0, AutoCommit => 1, sqlite_unicode => 1, } 
     ) or die $DBI::errstr; 
$dbh->do("CREATE TEMP TABLE $table (str TEXT, num INTEGER)"); 
my $sth = $dbh->prepare("INSERT INTO $table (str, num) VALUES (?, ?)"); 
$sth->execute('aaa', '111'); 
$sth->execute('bbb', '222'); 
$sth->execute('ccc', '333'); 

get '/eingabe' => sub { 
    my $self = shift; 
    $self->render('eingabe'); 
}; 

get '/search_db/:col' => sub { 
    my $self = shift; 
    my $col = $self->param('col'); 
    my $term = $self->param('term'); 
    my $sth = $dbh->prepare("SELECT DISTINCT $col FROM $table WHERE $col LIKE ?"); 
    $sth->execute($term . '%'); 
    my $ref; 
    while (my $row = $sth->fetchrow_arrayref()) { 
      push @$ref, @$row; 
    } 
    $self->render(json => $ref); 
}; 

app->start; 

__DATA__ 
@@ eingabe.html.ep 
<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="UTF-8" /> 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js"></script> 
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.js"></script> 
<script type="text/javascript"> 
    $(document).ready(function() { 
     var ids = [ 'str', 'num' ]; 
     for (var i = 0; i < ids.length; i++){ 
      $("#" + ids[i]).autocomplete({ 
       source: function(request, response){ 

        alert(ids[i]); // <--- 

        $.getJSON('/search_db/' + ids[i], request, function(data_from_server){ 
         var suggestions = []; 
         var len = data_from_server.length; 
         for(var i = 0; i < len; i++){ 
          suggestions.push(data_from_server[i]); 
         } 
         response(suggestions); 
        }); 
       } 
      }); 
     } 
    }); 
</script> 
</head> 
<body> 
<form> 
    <table> 
     <tr><td>String:</td><td><input type="text" id="str" name="str"" /></td></tr> 
     <tr><td>Number:</td><td><input type="number" id="num" name="num" /></td></tr> 
    </table><br /> 
    <input type="submit" value="OK"/> 
</form> 
</body> 
</html> 

答えて

3

あなたはここで説明しています問題持っているように聞こえる:Creating closures in loops: A common mistake

をおalertにお電話でundefinedを取得している理由はautocomplete関数が呼び出されたとき、あなたのためのループが終了した、ということです実行中のループ変数iの値は2、つまりids.length + 1です。そのため、ids[i]ids[2]と同じですが、ids配列には2つの要素しかないので存在しません。私は何が起こっているのかを説明するために、この動作の簡単なデモを考え出しました:結果を見るには、ブラウザのコンソールを開いておく必要があります。http://jsfiddle.net/ianoxley/KwXVs/1/

範囲を保持し、undefinedhttp://jsfiddle.net/ianoxley/BVa5Q/を参照)を取り除くのに役立つ余分なクロージャを作成する場合。あなたはこのような何かにあなたのコードを変更しようとした場合

うまくいけば、それは問題を取り除くになります。このことができます

$(document).ready(function() { 
    function initAutocomplete(element_id) { 
     $("#" + element_id).autocomplete({ 
      source: function (request, response) { 

       alert(element_id); // <--- 

       $.getJSON('/search_db/' + element_id, request, function (data_from_server) { 
        var suggestions = []; 
        var len = data_from_server.length; 
        for (var i = 0; i < len; i++) { 
         suggestions.push(data_from_server[i]); 
        } 
        response(suggestions); 
       }); 
      } 
     });   
    } 

    var ids = ['str', 'num']; 
    for (var i = 0; i < ids.length; i++) { 
     var current_id = ids[i]; 
     initAutocomplete(current_id); 
    } 
}); 

希望を。

+0

うん、それは私が言っていることをしようとしていたが、私は多くの急いでいた。良い説明。 –

0

あなたは二回i反復変数を定義している:それは再び$.getJSONコールにコールバックの内部で使用されています。

別の名前(j)の名​​前を変更する必要があります(例のみ)。

ので、それは言う:

$(document).ready(function() { 
    var ids = [ 'str', 'num' ]; 
    for (var i = 0; i < ids.length; i++){ 
     $("#" + ids[i]).autocomplete({ 
      source: function(request, response){ 

       alert(ids[i]); // <--- 

       $.getJSON('/search_db/' + ids[i], request, function(data_from_server){ 
        var suggestions = []; 
        var len = data_from_server.length; 
        for(var j = 0; j < len; j++){ 
         suggestions.push(data_from_server[j]); 
        } 
        response(suggestions); 
       }); 
      } 
     }); 
    } 
}); 

を私はこのことができます願っています!

+0

それを見ていないし、通常私はそれをしないだろう。しかし、私がJavaScriptで知っている限り、変数のスコープは関数なので、2番目の 'var i'は2番目の' var i'と宣言された関数の外で最初の 'var i'を混乱させるはずです。 –

0

ソースコールバック関数が有効範​​囲外です。あなたがforループが完了した後であるイベントがトリガされたときに呼び出されるイベントリンクへの関数を攻撃するとき。

コールバックを使用しているときは常に、その関数が必要とするものをすべて渡すか、オブジェクトが必要とするすべてをウィンドウオブジェクトに付けてグローバルに戻すことです。