我有这个喜欢和不喜欢评论的ajax功能但是有了这个功能,我可以同时喜欢和不喜欢。例如,当我喜欢评论时,它喜欢它,如果之后我不喜欢它也会这样做而不会删除我的喜欢。
以下是喜欢(upvote)和不喜欢(downvote)的代码
up votes
$(".tup").click(function (e) {
e.preventDefault();
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/upvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tup[data-id=' + reviewId + '] .vn').text(function (i, oldVal)
{
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
});
// down votes
$(".tdown").click(function (e) {
e.preventDefault();
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/downvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tdown[data-id=' + reviewId + '] .vn').text(function (i, oldVal) {
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
});
这是控制器的代码
public function upvote($id) {
if(!UpDownVote::where('review_id',$id)->where('upvote',1)->first()) {
Review::findOrFail($id)->increment('upvote');
UpDownVote::create([
'user_id' => Auth::user()->id,
'review_id' => $id,
'upvote' => 1
]);
return 'true';
} else {
return 'false';
}
}
public function downvote($id) {
if(!UpDownVote::where('review_id',$id)->where('downvote',1)->first()) {
Review::findOrFail($id)->increment('downvote');
UpDownVote::create([
'user_id' => Auth::user()->id,
'review_id' => $id,
'downvote' => 1
]);
return 'true';
} else {
return 'false';
}
}
答案 0 :(得分:0)
问题是您的Ajax调用是异步的;因此,当点击tup
按钮然后点击tdown
按钮时,当你点击第二个按钮时,perhas尚未完成治疗。
您可以在等待服务器响应时禁用单击的可能性。
var isClicking = false;
$(".tup").click(function (e) {
if(isClicking){
return;
}
isClicking = true;
e.preventDefault();
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/upvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tup[data-id=' + reviewId + '] .vn').text(function (i, oldVal)
{
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
}).always(function(){
isClicking=false;
});
});
// down votes
$(".tdown").click(function (e) {
e.preventDefault();
if(isClicking){
return;
}
isClicking = true;
var reviewId = $(this).data('id');
$.ajax({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: document.location.origin + '/review/' + reviewId + '/downvote',
type: 'POST',
data: {
review_id: reviewId
},
dataType: 'json'
})
.done(function (data) {
if (data == true) {
$('.tdown[data-id=' + reviewId + '] .vn').text(function (i, oldVal) {
return parseInt(oldVal, 10) + 1;
});
} else {
snackybar.timer("Already Voted", 3000);
}
})
.fail(function (jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
}).always(function(){
isClicking=false;
});
});