列表中的每封电子邮件都将发送到服务器,并且如果它是有效的电子邮件,则可以从服务器获取响应。
所以在检查完所有电子邮件后,阵列应该有:
joe@gmail.com - valid
abc@fjkdsl.com - invalid
xyz@yahoo.com - valid
test@nknk.com - invalid
在循环中将电子邮件发送到服务器的代码如下:
for(var i=0; i < isEmailValidList.length; i++) {
var isEmailValid = User.validateEmail({email : isEmailValidList[i].email}, function(){
isEmailValidList[i].isValid = isEmailValid.value;
});
}
但问题是调用是异步的,所以对于说i = 0,当我为0时控件不会进入函数内部。所以当它进入函数值时我可以是任何东西,主要是它大于数组的长度,因此isEmailValidList [i]未定义。如果调用是同步的,那么它将等待响应,我不会增加,但事实并非如此。
那么,如何为其相应的电子邮件获取正确的isValid响应?
答案 0 :(得分:5)
使用承诺。 Angular可以在没有任何&#34;特殊干预的情况下使用promises,就像为范围变量赋值一样,请参阅plnkr。承诺是&#34;基地&#34;驯服异步编程以便像同步编程一样工作(虽然我们在浏览器中没有javascript生成器)并且受到Angular团队的鼓励,因为它具有高度可测性和可维护性
http://plnkr.co/edit/8BBS2a1kC24BHBWRYp9W?p=preview
// trying to emulate your service here
var app = angular.module('app', []);
app.factory('User', function($q, $timeout){
User = {};
User.validateEmail = function(email){
var d = $q.defer();
$timeout(function(){
if (/(yahoo|gmail)/.test(email.email)){
d.resolve(email); // return the original object, so you can access it's other properties, you could also modify the "email" object to have isValid = true, then resolve it
} else {
d.resolve(); // resolve it with an empty result
}
}, 1000, false);
return d.promise;
};
return User;
});
app.controller('MainCtrl', function(User, $q){
this.emails = [
{email: 'joe@gmail.com', name: 'Joe'},
{email: 'abc@fjkdsl.com', name: 'Abc'},
{email: 'xyz@yahoo.com', name: 'XYZ'},
{email: 'test@nknk.com', name: 'test'}
];
this.isEmailValidList = [];
var promises = [];
for(var i=0; i < this.emails.length; i++) {
promises.push(
User.validateEmail(this.emails[i])
);
}
$q.all(promises).then(function(emails){
this.isEmailValidList = emails.filter(function(e){ return e; });
}.bind(this));
});
注意:$timeout
是模拟异步任务,如数据库调用等。您可以将整个电子邮件数组传递给验证服务,然后返回数组,而不是创建一个中间数组的promises。使用angular,您可以将范围变量分配给承诺,并且可以在ng-repeat
上使用它而无需对代码进行任何更改
答案 1 :(得分:3)
您可以使用闭包功能:
for (var i=0; i < isEmailValidList.length; i++) {
var isEmailValid = User.validateEmail({
email : isEmailValidList[i].email
}, (function(i) {
return function() {
isEmailValidList[i].isValid = isEmailValid.value;
};
})(i));
}