CakePHP 3.x Flash-сообщения для запросов ajax - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть приложение, написанное на CakePHP 3.5.13

Используется Flash Component , встроенный в Cake. Все это работает при стандартной настройке, например

// src/Controller/SomeController.php
public function foo()
{ 
    $this->Flash->set('Records updated', ['element' => 'success']);
    return $this->redirect(['action' => 'index']);
}

// src/Template/SomeController/index.ctp
<?= $this->Flash->render() ?>

Так что, если я получу доступ к /some-controller/foo, он установит флэш-сообщение, перезагрузит index.ctp и отобразит его.

Однако я хочу изменить вещи так, чтобы все это делалось с помощью вызовов ajax.

Если я создаю новый шаблон, /src/Template/SomeController/index.ctp и использую следующий jquery:

$('.foo-test').click(function(e) {
    e.preventDefault();

    $.ajax({
        url: '/some-controller/foo'
    }).done(response) {
       //console.log(response);
       window.location.href = '/some-controller/index'; 
    });
});

Когда я нажимаю на якорь с классом .foo-test, он отправляет запрос ajax.

Но при перезагрузке страницы (window.location.reload) не отображается флэш-сообщение. Почему, потому что это эквивалентно перезагрузке браузера /some-controller/index, верно?

Единственный способ изменить это - заставить foo() вернуть ответ JSON. Там, где я использовал console.log(response), я мог бы получить доступ к данным ответа и определить результат, а затем добавить флэш-сообщение, например,

 if (response.success !== '') {
     $('#outcome').html(response.success).addClass('alert alert-success');
 }

Который написал бы ответное сообщение в div с идентификатором #outcome и добавил бы соответствующие классы для стилизации.

Конечно, есть лучший способ, чем этот, поскольку он будет включать в себя переписывание каждого метода, где мне нужно было это сделать?

Почему не выполняется функция контроллера с последующей перезагрузкой страницы с помощью jquery, имея в виду, что она все равно может получить доступ к $_SESSION при выполнении таких действий?

Я посмотрел на плагины, но хочу знать, есть ли собственный Cake способ сделать это, что я пропускаю? Ajax не упоминается в документации по компонентам Flash.

1 Ответ

0 голосов
/ 04 сентября 2018

Хорошо, я понял это с помощью @ndm в комментариях.

Решение состоит в том, чтобы удалить перенаправление PHP в SomeController::foo():

public function foo()
{ 
    // There is no template (foo.ctp) associated with this function.
    $this->autoRender = false;

    $this->Flash->set('Records updated', ['element' => 'success']);

    // Remove line below:
    //return $this->redirect(['action' => 'index']);
}

Это потому, что мы делаем эквивалентный редирект в jquery:

window.location.href = '/some-controller/index'; 

Таким образом, ajax-запрос к /some-controller/foo все еще устанавливает флэш-сообщения. Использование перенаправления jquery перезагружает index.ctp, который затем содержит код для рендеринга флэш-сообщения.

Если вы выполняете рефакторинг кода для таких действий, вам нужно убедиться, что действие, эквивалентное foo() в этом примере, просто устанавливает флэш-сообщения и ничего не выводит. Вы можете достичь этого с помощью $this->autoRender = false, а затем использовать $this->Flash->set() как обычно, чтобы установить свои сообщения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...