[英]TypeError: this.element is null, Rails with Judge gem
I am building simple client side valditation using Judge gem. 我正在使用Judge gem建立简单的客户端评估。
Everything worked perfect till I choosed to run validations on "blur" instead of button click. 在我选择对“模糊”运行验证而不是单击按钮之前,一切工作都非常完美。
Script: 脚本:
var divs = ["advertisement_age","advertisement_weight","advertisement_region_id","advertisement_height","advertisement_name","advertisement_phone_number","Record_Start_Time",
"Record_End_Time","Record_Start_Time2","Record_End_Time2","advertisement_description", "advertisement_description_ru", "advertisement_terms_of_service"];
var arrayLength = divs.length;
var error_count =0;
for (var i = 0; i < arrayLength; i++) {
$(document.getElementById(divs[i])).blur(function(){
judge.validate(document.getElementById(divs[i]), { // This line causes error
valid: function(element) {
element.style.border = '1px solid green';
},
invalid: function(element, messages) {
element.style.border = '1px solid red';
// alert(messages.join(','));
}
});
});
}
In Mozzila Firebug there isn't any error message when I reload page. 在Mozzila Firebug中,当我重新加载页面时没有任何错误消息。 Error shows up when blur event is triggered. 触发模糊事件时显示错误。
Error message: 错误信息:
TypeError: this.element is null
this.attrValidators = root.JSON.parse(this.element.getAttribute('data-validate')...
I don't understand why it crashes at second document.getElementById(divs[i])
instead of the first if that array is valid? 我不明白为什么它在第二个document.getElementById(divs[i])
而不是第一个崩溃的情况下崩溃document.getElementById(divs[i])
如果该数组有效)?
Any suggestions ? 有什么建议么 ?
Thanks 谢谢
The problem is that by the time the blur
event fires, the for
loop has exited and the value of i
will be set to the last value it arrived at when the for
loop exited. 问题在于,当blur
事件触发时, for
循环已退出,并且i
的值将设置为for
循环退出时到达的最后一个值。 Then, eventually, when the blur
event fires judge.validate(document.getElementById(divs[i])
will fail because i
is not what you expected. One way to fix it is by forming a closure over the value of i
: 然后,最终,当blur
事件触发时, judge.validate(document.getElementById(divs[i])
会失败,因为i
不是您期望的那样。一种解决方法是通过对i
的值形成闭包:
for (var i = 0; i < arrayLength; i++) {
(function(index) { // index is the current i value
$(document.getElementById(divs[index])).blur(function() {
judge.validate(document.getElementById(divs[index]), {
valid: function(element) {
element.style.border = '1px solid green';
},
invalid: function(element, messages) {
element.style.border = '1px solid red';
// alert(messages.join(','));
}
});
});
})(i); // pass i to the immediately executing anonymous function (closure)
}
So we put the $.blur
code inside a closure and pass i
in. Inside the closure i
will be called index
. 因此,我们将$.blur
代码放入闭包中并传递给i
。在闭包内, i
将称为index
。 The value of index
will be the expected value at the time the loop executed the code, and will remain that way after the loop exits. index
的值将是循环执行代码时的期望值,并在循环退出后保持该值。 Notice how inside the blur
handler we're now using divs[index]
. 注意我们现在在blur
处理程序中如何使用divs[index]
。
The thing to take away from this particular problem is that the blur
event handler function is asynchronous and won't evaluate divs[i]
until the blur event happens which will be at a time after the for
loop has exited and left the value of i
at its last value i == arrayLength - 1
. 解决这个特定问题的方法是, blur
事件处理程序函数是异步的,直到模糊事件发生(直到for
循环退出并保留i
的值)后,才会评估divs[i]
。在其最后一个值i == arrayLength - 1
。
Here's some more reading on that: Calling an asynchronous function within a for loop in JavaScript 这方面的更多信息: 在JavaScript中的for循环内调用异步函数
Another way to fix this would be to save the element you find with document.getElementById(divs[i])
and then use this
inside the handler: 解决此问题的另一种方法是保存使用document.getElementById(divs[i])
找到的元素,然后在处理程序中使用this
元素:
for (var i = 0; i < arrayLength; i++) {
var field = $(document.getElementById(divs[i]));
field.blur(function() {
judge.validate(this, { // `this` is the field element
valid: function(element) {
element.style.border = '1px solid green';
},
invalid: function(element, messages) {
element.style.border = '1px solid red';
// alert(messages.join(','));
}
});
});
}
I'd choose the latter solution as it is cleaner. 我选择后一种解决方案,因为它更清洁。 Just wanted to explain the closure thing first. 只是想先解释一下关闭的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.