Reputation:
I have been trying to resolve this issue in these few days, basically i am trying to have commetn and child comments, the comment has a button/link called 'retrievecomment' to retrieve child comment.
I found out that The pjax is not working, it keeps refreshing the whole page.
<div class="row">
<?= $model['comment']?>
</div>
<div class="row">
<div id="selector"align="right">
<?= Html::a('Retrieve Comment', ["../../thread/index?id=" . $model['thread_id'] . "&comment_id=" . $comment_id],
['data-pjax' => '#childCommentData-'.$comment_id, 'class' => 'btn btn-default'
,'id' => 'retrieveComment' . $comment_id]) ?>
</div>
<?php Pjax::begin([
'id' => 'childCommentData-'.$comment_id,
'clientOptions'=>[
'timeout' => 5000,
'registerClientScript' => "$.pjax.reload({container:'#childCommentData-$comment_id'});",
'linkSelector'=>'#retrieveComment'.$comment_id
]
]);?>
<div class="col-md-12">
<?php if(isset($retrieveChildData)){ ?>
<?= ListView::widget([
'dataProvider' => $retrieveChildData,
'options' => [
'tag' => 'div',
'class' => 'list-wrapper',
'id' => 'list-wrapper',
],
'layout' => "\n{items}\n{pager}",
'itemView' => function ($model, $key, $index, $widget) {
return $this->render('_list_child_comment',['model' => $model]);
},
'pager' => [
'firstPageLabel' => 'first',
'lastPageLabel' => 'last',
'nextPageLabel' => 'next',
'prevPageLabel' => 'previous',
'maxButtonCount' => 3,
],
]) ?>
<?php } ?>
</div>
<?php Pjax::end();?>
</div>
</div>
The Pjax for the comment is called multiple times inside the listview , i believe this has become the problem since the compiler confused which pjax to be reloaded,
Controller code (inside actionIndex)
else if(!empty($_GET['comment_id'])){
$comment_id = $_GET['comment_id'];
//retrieve yes data
$retrieveChildData = new SqlDataProvider([
'sql' => Comment::retrieveChildComment($comment_id),
'totalCount' => Comment::countChildComment($comment_id),
'pagination' => [
'pageSize' =>5,
],
]);
return $this->render('_list_comment.php', ['retrieveChildData' => $retrieveChildData]);
}
Upvotes: 3
Views: 2883
Reputation: 1296
Usually the whole-page-refresh of pjax has two possible sources:
This one is easy and it looks like you figured it out yourself already. You only have to increase the pjax-timeout value. You can do this on each widget-instance individually or just set it globally like this:
if ($.pjax) {
$.pjax.defaults.timeout = 5000;
}
The code above sets the default timeout for all pjax-instances to 5000ms. Usually more than enough. The usual default value of 650ms is rather tight for complex web-applications.
You can find all options on the official site: here
This is a bit trickier and it looks like this is your problem here. To find out, look at your debug toolbar and make sure you preserve the log accross pages (in chrome this settings name is preserve log
under the network tab. If you see multiple requests fire, this is your problem!
If so, you have to first implement your own check to ensure no additional pjax request fires while there still are some running. If you don't and a user clicks two buttons fast after each other you'll run into this no matter what.
I usually prevent this by implementing a counter of how many ajax requests are running. If the counter is 0 I trigger the new request, otherwise i'll wait.
Example for an ajax-counter:
//this is the actual counter
var ajaxCounter = 0;
//this method is called whenever an ajax-request fires
$(document).ajaxSend(function() {
ajaxCounter++;
});
//this method is called whenever an ajax-request finishes...no matter of its result
$(document).ajaxComplete(function() {
ajaxCounter--;
});
//check if pjax calls are allowed right now
var pjaxAllowed = function () {
return ajaxCounter == 0;
}
Et voilà! Before you trigger your pjax you simply check if ajaxCounter == 0
or use the convenience-function pjaxAllowed()
as shown above. If you don't want to check this each and every time you could implement your own little pjax-request-stack. Doing so is very easy with the events pjax provides: Pjax-Events
I hope I could help you out. This one gave me some headaches as well ;)! If you need some more infos just let me know...
preserve logs
within the network tab of the dev tools of Chrome is checked. Otherwise you lose track of the requests when the page gets reloadeddata-pjax="0"
to them. This indicates that no refresh is desired if this link is clicked.Upvotes: 7