Jak używać messageManager, aby pokazać błąd po przekierowaniu

23

Mam moduł, który przetwarza akcję Post, a następnie przekierowuje.

Teraz są przypadki błędów i chciałbym pokazywać użytkownikom wiadomości.

Wiem już, że ten kod dodaje komunikat do sesji.

$this->messageManager->addError(
   $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message)
);

Ale nie wiem, jak uruchomić renderowanie.

Obecnie jest pokazywany tylko wtedy, gdy wykonuję inną akcję, która już działa w ten sposób.

Na przykład login z niewłaściwym hasłem.

Flyingmana
źródło
znajdziesz jakieś rozwiązanie tego problemu?
Shaheer Ali,
1
jest już wbudowana funkcja sprawdzania. Zobacz moją odpowiedź: magento.stackexchange.com/a/219143/33057
Khoa TruongDinh
ten kod gdzie jest dodawany?
SUDHAKAR ARUNACHALAM

Odpowiedzi:

22

Musisz użyć metody wstrzykiwania obiektów w klasie akcji modułu ur, aby wstrzyknąć do niego obiekt menedżera komunikatów, podałem przykład tego, co możesz zrobić. Mam nadzieję, że to pomoże

class Example
{
    protected $_messageManager;

    public function __construct(
        \Magento\Framework\Message\ManagerInterface $messageManager
    ) {
        $this->_messageManager = $messageManager;
    }

    public function method( ) {
        ..
        $message = '...';
        $this->_messageManager->addError($message);
        ..
    }
}
Karvin Ong
źródło
czy jest jakaś funkcja getError? chcę pobrać wiadomość
jafar pinjar
1
addErrormetoda jest przestarzałe powinny być teraz addErrorMessage
jamil
@jafarpinjar, nope. Zmieniłbym to w tłumaczeniu, ale jeśli nie możesz go zmienić w tłumaczeniu, możesz otrzymać komunikat o błędzie przez obserwatora zdarzeń i tam manipulować.
Karvin Ong
@jamil, tak zgodził się. addError jest nieaktualny, ale nadal obsługiwany w wersji 2.3.1 :)
Karvin Ong
6

Nie jestem pewien, czy tego właśnie szukasz, ale daję temu szansę.
Możesz pobrać takie wiadomości:

$messages = $this->messageManager->getMessages(true);  

gdzie messageManagerjest instancja \Magento\Framework\Message\ManagerInterface.

W rdzeniu jest to używane do wywołań ajax w celu zwrócenia komunikatów o błędach w odpowiedzi JSON w następujący sposób \Magento\Catalog\Controller\Adminhtml\Category\Move:

$block = $this->layoutFactory->create()->getMessagesBlock();
...
$block->setMessages($this->messageManager->getMessages(true));
$resultJson = $this->resultJsonFactory->create();

return $resultJson->setData([
    'messages' => $block->getGroupedHtml(),
    'error' => $error
]);

W przypadku akcji z wyjściem nie powinieneś nic robić (tak myślę). Plik default.xmlukładu z Magento_Thememodułu zawiera już ten blok, <block class="Magento\Framework\View\Element\Messages" name="messages" as="messages" template="Magento_Theme::messages.phtml"/>który powinien obsługiwać komunikaty.

[Uwaga dodatkowa]:
Nie używaj $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message). Wstrzyknij do swojego konstruktora instancję Magento\Framework\Escaperi użyj jej.

Marius
źródło
Akcja loginPost jest również w stanie to wyzwolić, a następnie przekierowuje na stronę logowania i pokazuje to następnie. Tak też jest ze mną. Bez ajax, bez tej samej strony.
Flyingmana
Tak powiedziałem ... powinno to być obsługiwane domyślnie. Nie powinieneś dokonywać żadnych zmian. Komunikat o sesji powinien zostać wyświetlony na następnej stronie.
Marius
2
I dlatego zadaję to pytanie. Ponieważ nie jest. Przekierowuję nawet na tę samą stronę (login), więc oczywiście potrzebny jest dodatkowy krok. Jak już powiedziałem, nawet na stronie logowania moja wiadomość jest wyświetlana dopiero po próbie zalogowania się, która publikuje własną wiadomość
Flyingmana
1
DOBRZE. Będę kopać głębiej. To wydaje mi się dziwne.
Marius
1
@Flyingmana. Znalazłem coś. Wiadomości z sesji są pobierane po nawiązaniu połączenia z /customer/section/load/. Może to pomaga.
Marius
4

można również znaleźć menedżera wiadomości, $contextktóry jest dostępny poprzez wstrzyknięcie do konstruktorów akcji:

class yourAction extends \Magento\Framework\App\Action\Action
{
    /** var ... */
    protected $_messageManager;

    public function __construct(Context $context)
    {
        $this->_messageManager = $context->getMessageManager();
        parent::__construct($context);
    }

Następnie wystarczy użyć, jak wspomniano w odpowiedziach powyżej

$ this -> _ messageManager-> addError ($ message);

Mam nadzieję, że to pomoże

medmek
źródło
2

Dla mnie wygląda na to, że musisz dodać specjalny blok dla swoich wiadomości, jeśli chcesz pokazać je w sposób inny niż JS.

Na przykład w Magento \ Checkout \ view \ frontend \ layout \ checkout_cart_index.xml znajduje się:

<referenceContainer name="page.messages">
    <block class="Magento\Checkout\Block\Cart\ValidationMessages" name="checkout.cart.validationmessages"/>
</referenceContainer>

Magento\Checkout\Block\Cart\ValidationMessagesblok rozszerza blok podstawowy \Magento\Framework\View\Element\Messagesodpowiedzialny za renderowanie wiadomości.

Bloki zdefiniowane w default.xmlsą tylko dla wiadomości JS.

Michał Biarda
źródło
Jak go dodać checkout_index_index.xml?
Stevie G,
1

Spojrzeć na

vendor / magento / module-customer / view / frontend / web / js / customer-data.js

/**
 * Events listener
 */
$(document).on('ajaxComplete', function (event, xhr, settings) {
    var sections,
        redirects;

    if (settings.type.match(/post|put/i)) {
        sections = sectionConfig.getAffectedSections(settings.url);

        if (sections) {
            customerData.invalidate(sections);
            redirects = ['redirect', 'backUrl'];

            if (_.isObject(xhr.responseJSON) && !_.isEmpty(_.pick(xhr.responseJSON, redirects))) {
                return;
            }
            customerData.reload(sections, true);
        }
    }
});

Jak widzimy, jest już wbudowana funkcja sprawdzania . Jeśli nasza odpowiedź zawiera słowa kluczowe: 'redirect', 'backUrl'wiadomość zostanie załadowana po przekierowaniu.

  • Po zakończeniu aukcji klient zostanie unieważniony. Będzie to „wyzwalająca” sesja ponownego ładowania wiadomości.
  • Sprawdzanie słowa kluczowe: 'redirect', 'backUrl'.
Khoa TruongDinh
źródło