为什么我来alert
打电话给undef
?
#!/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>
答案 0 :(得分:3)
听起来你遇到了这里解释的问题:Creating closures in loops: A common mistake
您在调用undefined
时获得alert
的原因是,当调用autocomplete
函数时,您的for循环已完成执行意味着您的循环变量{{ 1}}的值为2,即i
。因此ids.length + 1
与ids[i]
相同,因为您的ids[2]
数组中只有2个元素,因此不存在ids
。我试图想出这个行为的简单演示来帮助说明发生了什么:http://jsfiddle.net/ianoxley/KwXVs/1/(你需要打开浏览器的控制台才能看到结果)。
如果你创建了一个额外的闭包,它应该有助于保留你的范围并摆脱undefined
(见http://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);
}
});
希望这有帮助。
答案 1 :(得分: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 );
});
}
});
}
});
我希望这有帮助!
答案 2 :(得分:0)
您的源回调函数超出范围。当你将一个函数攻击到一个事件链接时,它会在你的for循环完成后触发事件时被调用。
使用回调时,一个好的经验法则是始终传递该函数所需的所有内容,或将对象所需的所有内容附加到窗口对象并将其全局化。