вложенный pjax

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
caHek2x
Сообщения: 1117
Зарегистрирован: 2016.04.12, 20:41

вложенный pjax

Сообщение caHek2x » 2017.10.13, 03:43

есть 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 ... ?

caHek2x
Сообщения: 1117
Зарегистрирован: 2016.04.12, 20:41

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

Сообщение caHek2x » 2017.10.13, 03:53

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

Аватара пользователя
Alexum
Сообщения: 461
Зарегистрирован: 2016.09.26, 10:00

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

Сообщение Alexum » 2017.10.13, 09:20

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

pavlm
Сообщения: 69
Зарегистрирован: 2013.09.02, 16:33

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

Сообщение 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 ...

caHek2x
Сообщения: 1117
Зарегистрирован: 2016.04.12, 20:41

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

Сообщение caHek2x » 2017.10.13, 14:09

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

caHek2x
Сообщения: 1117
Зарегистрирован: 2016.04.12, 20:41

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

Сообщение caHek2x » 2017.10.13, 14:10

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 события ... ?! или это как то проще переопределяется ?

pavlm
Сообщения: 69
Зарегистрирован: 2013.09.02, 16:33

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

Сообщение pavlm » 2017.10.13, 16:38

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

caHek2x
Сообщения: 1117
Зарегистрирован: 2016.04.12, 20:41

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

Сообщение caHek2x » 2017.10.13, 16:58

пришла такая мысль что каждый раз при генерации задавать новый 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]]); ?>
должно сработать ... протестирую позже ...

Ответить