Страница 1 из 1

вложенный pjax

Добавлено: 2017.10.13, 03:43
caHek2x
есть pjax ...
внутри него есть форма, форма добавления комментария ...
и еще внутри него есть комментарии обернутые тоже в pjax т.к. у каждого комментария есть форма ответа ...

так вот когда я добавляю ответы то обновляется только блок с самим комментарием не трогая другие комментарии ... отрабатывает внутренний pjax ...
когда же я добавляю комментарий то обновляются все комментарии ... чтоб отобразить новый ... это отрабатывает внешний pjax ... и вот после этого начинает творится магия, у старых комментариев форма при отправке отправляет два раза почемуто
в логах браузера я наблюдаю такую картину ...

Код: Выделить всё

add?doc_id=138&answer=483	POST	(canceled)	xhr	jquery.js:9175	0 B	21 ms
add?doc_id=138&answer=483	POST	200	xhr	jquery.js:9175	9.9 KB	2.29 s
но хоть и пишется почемуто что второй запрос отменен (вообще не понятно откуда второй запрос) но до сервера доходят оба ...
код сократил чтоб div и прочее не мешало ... вот как это выглядит:

Код: Выделить всё

<?
$pjax_id = 'pj_comments';
Pjax::begin([
	'enablePushState' => false,
	'id'              => $pjax_id,
	'formSelector'    => '#'.$pjax_id.' form[data-pjax-comments]',
	'linkSelector'    => '#'.$pjax_id.' a[data-pjax-comments]'
]);
?>
	<? foreach($comments as $comment): ?>
		<?//------------------------------------------?>
		<?
		$pjax_id = 'pj_comment_'.$comment->comment_id;
		Pjax::begin([
			'enablePushState' => false,
			'id'              => $pjax_id,
			'formSelector'    => '#'.$pjax_id.' form[data-pjax-comment]',
			'linkSelector'    => '#'.$pjax_id.' a[data-pjax-comment]'
		]);
		?>
			<? $form = ActiveForm::begin(['action' => Url::toRoute(['/manual/doc-comment/add', 'doc_id' => $doc_id, 'answer' => $comment->comment_id]), 'options'=>['data-pjax-comment' => 1]]); ?>
				<textarea class="form-control" id="answer_<?=$comment->comment_id?>" name="comment" style="vertical-align: bottom; resize: none" rows="1"></textarea>
				<button class="btn btn-success" type="submit">Ответить</button>
			<? ActiveForm::end() ?>
		<? Pjax::end(); ?>		
		<?//------------------------------------------?>
	<? endforeach; ?>

	<? $form = ActiveForm::begin(['action' => Url::toRoute(['/manual/doc-comment/add', 'doc_id' => $doc_id]), 'options' => ['data-pjax-comments' => 1]]); ?>
		<textarea class="form-control" id="comment" name="comment" style="vertical-align: bottom; resize: none" rows="1"></textarea>
		<button class="btn btn-success" type="submit">Добавить <span class="hidden-xs">комментарий</span></button>
	<? ActiveForm::end() ?>
<? Pjax::end(); ?>
чтоб было понятнее визуально что не так:
https://yadi.sk/d/eDf8gWkD3Ni7NJ
  • добавляем комментарий "1" - все ок, отрабатывает pj_comments
  • добавляет ответ "2" - все ок, отрабатывает pj_comment_....
  • добавляет ответ "3" - все ок, отрабатывает pj_comment_....
  • добавляем комментарий "4" - все ок, отрабатывает pj_comments
    и вот тут ломается старая форма с комментарием "1"
  • добавляет ответ "5" - видим в дебаге что летит два запроса "add?doc..." один из них canceled ... в итоге на сервер прилетает 2 запроса и вставляется два комментария
  • новый комментарий "4" работает отлично, проверяем:
    добавляет ответ "6" - все ок, отрабатывает pj_comment_....
  • добавляет ответ "7" - все ок, отрабатывает pj_comment_....
  • еще раз смотрим на комментарий "1" добавляем там ответ
    добавляет ответ "8" - видим в дебаге что летит два запроса "add?doc..." один из них canceled ... в итоге на сервер прилетает 2 запроса и вставляется два комментария
я уже и пробовал формам каждый раз рендомный ид генерировать ... не помогает ... в чем беда .. .почему pjax два раза делает submit ... ?

Re: вложенный pjax

Добавлено: 2017.10.13, 03:53
caHek2x
единственный выход который вижу это убрать вложенный pjax ... и при добавлении ответа отдавать на рендер не только этот комментарий с его ответами а все комментарии ... так работает ... но хотелось бы понять почему вложенный pjax так не корректно себя ведет .. .и что за это отмененные запросы летят ...

Re: вложенный pjax

Добавлено: 2017.10.13, 09:20
Alexum
А вы уверены, что у вложенных ActiveForm генерируются уникальные id для form а не дублирующиеся? Может самостоятельно их задавать? Что происходит, когда комментариев становится больше двух?

Re: вложенный pjax

Добавлено: 2017.10.13, 13:05
pavlm
Двойные запросы потому, что два раза устанавливается обработчик сабмита для внутренних pjax ( jQuery(document).on('submit', ...) ) .
А двойной обработчик из-за того, что при обновлении внешнего pjax, внутренние pjax устанавливаются еще раз и при этом ранее установленые обработчики не сбрасываются.
Решить можно установкой сабмит обработчика не на документ, а на pjax-элемент, типа этого:

Код: Выделить всё

jQuery("#pjax-div").on("submit", 'form[data-pjax]', function (event) {jQuery.pjax.submit ...

Re: вложенный pjax

Добавлено: 2017.10.13, 14:09
caHek2x
Alexum писал(а): 2017.10.13, 09:20 А вы уверены, что у вложенных ActiveForm генерируются уникальные id для form а не дублирующиеся? Может самостоятельно их задавать? Что происходит, когда комментариев становится больше двух?
написал об этом ...
caHek2x писал(а): 2017.10.13, 03:43 ....
я уже и пробовал формам каждый раз рендомный ид генерировать ... не помогает ...

Re: вложенный pjax

Добавлено: 2017.10.13, 14:10
caHek2x
pavlm писал(а): 2017.10.13, 13:05 Двойные запросы потому, что два раза устанавливается обработчик сабмита для внутренних pjax ( jQuery(document).on('submit', ...) ) .
А двойной обработчик из-за того, что при обновлении внешнего pjax, внутренние pjax устанавливаются еще раз и при этом ранее установленые обработчики не сбрасываются.
Решить можно установкой сабмит обработчика не на документ, а на pjax-элемент, типа этого:

Код: Выделить всё

jQuery("#pjax-div").on("submit", 'form[data-pjax]', function (event) {jQuery.pjax.submit ...
отказаться от pjax юишной обертки ... и самому задавать pjax события ... ?! или это как то проще переопределяется ?

Re: вложенный pjax

Добавлено: 2017.10.13, 16:38
pavlm
Переопределить похоже не получится, можно отключить стандартный обработчик через formSelector = false, и самому добавить нужный js.
Кривовато, но работает.

Re: вложенный pjax

Добавлено: 2017.10.13, 16:58
caHek2x
пришла такая мысль что каждый раз при генерации задавать новый formSelector

то есть

Код: Выделить всё

$form_data = 'data-pjax-comment_'.time();
'formSelector'    => '#'.$pjax_id.' form['.$form_data.']',
ну и у формы вместо

Код: Выделить всё

<? $form = ActiveForm::begin([....... 'options'=>['data-pjax-comment' => 1]]); ?>
впихивать

Код: Выделить всё

<? $form = ActiveForm::begin([....... 'options'=>[$form_data => 1]]); ?>
должно сработать ... протестирую позже ...