1 Отредактировано Закусило Александр (16.11.2016 19:29:42)

Тема: Как сделать Ajax запрос блок контроллеру в Readyscript?

Вопрос:
Как сделать Ajax запрос блок контроллеру в Readyscript?

Ответ:
Дело в том, что каждый блок контроллер в системе обладает своим уникальным идентификатором. Заботится о нём не надо, т.к. как только вы его вставляете на страницу, то тут же у него генерируется уникальный номер. Это нужно для того, чтобы можно было вставить несколько таких же блок контроллеров или же разных, но чтобы именно тот который Вам нужно отработал.
Соответственно когда вы посылаете запрос, то надо передавать уникальный идентификатор блока в параметре с именем "_block_id".
Т.е. например

 
?_block_id=-345345431

Как его получить?
В шаблоне доступна переменная $this_controller у которой есть метод getBlockId, его то и можно использовать, например так

/путь к блок контроллеру/?_block_id={$this_controller->getBlockId()}

Если вы реализуете форму, то есть метод, который вернёт скрытый input с прописанным id блока, который будет учитываться при отправке формы.

<form>
{$this_controller->myBlockIdInput()}
....
</form>

Т.е. в общем виде, если мы в блок контроллере реализуем пагинацию, то урл в шаблоне можно получить так:

{$router->getUrl('catalog-block-sidefilters', ['_block_id'=>$this_controller->getBlockId(), 'p'=>2])}

Т.е. используя объект $router. В данном примере это страница со списком товаров, и где-то там наш блок контроллер.

И тогда получится адрес примерно такой:

/catalog-block-sidefilters/?_block_id=-342342345&p=2

Ну хорошо, вот мы отправили запрос.
Как понять на стороне контроллера, какому контроллеру пришёл запрос и сделать обработку этого запроса?

Всё просто. В нашем блок контроллере пишем...
Для POST запроса:

if ($this->isMyPost()){
   //Мой POST запрос
}

Для GET запроса:

if ($this->myGet()){
   //Мой GET запрос
}

Если есть вопросы, задавайте.

2

Re: Как сделать Ajax запрос блок контроллеру в Readyscript?

Во фронт контроллере можно добавить секцию к ответу и если это аякс запрос, то в возвращаемом JSON будет эта секция. Но вот блок-контроллер всегда возвращает HTML - можно как-то получить JSON результат со спец секциями для блока?

Повысить оценку Понизить оценку

3 Отредактировано Закусило Александр (14.11.2016 17:25:01)

Re: Как сделать Ajax запрос блок контроллеру в Readyscript?

У нас всегда возвращается JSON, если Ajax. Но это в том случае если в блок контроллере возвращается через return $this->result. Но у нас вроде везде такая тема. Возможно система не может отпределить, что у Вас это Ajax запрос из-за NGINX на https. Если да, то смотрите сюда:
http://blog.chrismeller.com/getting-php … g-in-nginx

4 Отредактировано Игорь (16.11.2016 17:44:30)

Re: Как сделать Ajax запрос блок контроллеру в Readyscript?

Да возвращается JSON, но только в блок контроллере нет метода wrapOutput() - из-за этого возвращается HTML всей страницы и только в месте блока - JSON строка.

function getOutput()
    {
        $this->result['html'] = $this->getHtml();
        if ($this->controller->url->isAjax() && $this->checkAjaxOutput) {

            /*===== Смотрим на условие ниже =====*/

            if ($this->controller instanceof \RS\Controller\Front || $this->controller instanceof \RS\Controller\Admin\Front) {
                // Это работает толька для фронт и бек контроллеров, как видно из условия
                $this->controller->wrapOutput(false);
            }
            return json_encode($this->result);
        } else {            
            if ($this->noAjaxRedirect !== null) {
                $this->controller->redirect($this->noAjaxRedirect);
            }
            return isset($this->result['html']) ? $this->result['html'] : '';
        }
    }

Вот и получается, что блок не может вернуть чистый JSON.

Для чего это может быть нужно:
Например, у нас на сайте есть форма подписки на рассылку. Для этой формы я сделал блок, который выводит эту самую форму и обрабатывает её отправку. Я хочу сделать отправку через AJAX запрос и с фронт котроллером это очень удобно делать, потому что можно добавить любую доп. информацию в секции (статус, код ошибки и т.п.). А для блока приходится искать в html с результатом нужный блок и заменять старый html новым. Не говоря о том, что не доступна информация из секций.

Понятно, что можно сделать отдельный фронт контроллер, который будет обрабатывать форму и возвращать JSON, но, по моему, если бы блок отдавал JSON в ответ на AJAX - было бы очень круто!

Повысить оценку Понизить оценку

5

Re: Как сделать Ajax запрос блок контроллеру в Readyscript?

JSON для блока:
https://dl.dropboxusercontent.com/s/tm06a9xjv2s9l5j/shot_161116_154605.png

Экшн контроллера:

public function actionIndex()
    {
        if ($this->isMyPost()) {
            $email = $this->request('email', TYPE_STRING);

            if ($this->api->subscribeUser($email, $this->getParam('list_id'))) {
                $this->view->assign('success', t('Вы успешно подписались на рассылку новостей'));
            } else {
                $this->view->assign('error', t('Произошла ошибка в процессе подписки на рассылку'));
            }

            if ($this->url->isAjax()) {
                $this->result->checkAjaxOutput(true); // Форсим AJAX
                $this->result->addSection('test', 'Foo'); // Пробуем всунуть секцию

                return $this->result->setTemplate($this->getParam('indexTemplate'));
            }
        }

        return $this->result
            ->setTemplate($this->getParam('indexTemplate'));
    }

Повысить оценку Понизить оценку

6 Отредактировано Закусило Александр (16.11.2016 18:59:53)

Re: Как сделать Ajax запрос блок контроллеру в Readyscript?

А вы как обращаетесь к блоку? Какой урл у Вас в Ajax уходит?
Я бы кстати сделал бы вот так:

public function actionIndex()
    {
        if ($this->isMyPost()) {
            $email = $this->request('email', TYPE_STRING);

            if ($this->api->subscribeUser($email, $this->getParam('list_id'))) {
                $this->view->assign('success', t('Вы успешно подписались на рассылку новостей'));
            } else {
                $this->view->assign('error', t('Произошла ошибка в процессе подписки на рассылку'));
            }

            if ($this->url->isAjax()) {
                $this->result->checkAjaxOutput(true); // Форсим AJAX
                $this->result->addSection('test', 'Foo'); // Пробуем всунуть секцию
            }
        }

        return $this->result->setTemplate($this->getParam('indexTemplate'));
    }

Будет короче:)

7 Отредактировано Закусило Александр (16.11.2016 19:30:16)

Re: Как сделать Ajax запрос блок контроллеру в Readyscript?

Кажись понял. У Вас старая информация.  Я вверху поправил. Но на всякий случай...
Т.е. в общем виде, если мы в блок контроллере реализуем пагинацию, то урл в шаблоне можно получить так:

{$router->getUrl('catalog-block-sidefilters', ['_block_id'=>$this_controller->getBlockId(), 'p'=>2])}

Т.е. используя объект $router. В данном примере это страница со списком товаров, и где-то там наш блок контроллер.

И тогда получится адрес примерно такой:

/catalog-block-sidefilters/?_block_id=-342342345&p=2

8 Отредактировано Игорь (16.11.2016 20:19:22)

Re: Как сделать Ajax запрос блок контроллеру в Readyscript?

Всё, до меня дошло) У меня в форме экшн не указан и по этому у меня в результате был html всей страницы

Спасибо!

Повысить оценку Понизить оценку