Magento 2: наблюдатель событий для выбора способа оплаты

13

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

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

введите описание изображения здесь

Дирен Васоя
источник

Ответы:

10

К сожалению, наблюдатели полезны только внутри функций php. Это означает, что для запуска события оно должно первоначально отправляться dispatch()собственным или пользовательским диспетчером событий. В данном конкретном случае предпринимаемое действие - это нажатие кнопки «Способ оплаты». Этот щелчок не запускает выполнение php-кода, выполняется только код Javascript.

Поскольку процесс оформления заказа в Magento 2 в основном построен на Knockout JS, большинство действий происходит на внешнем интерфейсе с использованием Javascript вместо php на стороне сервера.

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

Хорошим углом зрения для вашего проекта будет использование контроллера вместо наблюдателя:

1. Начнем с создания модуля ...

2. Создайте контроллер, который выполняет вашу логику при срабатывании

Структура контроллера: http://www.example.com/route/controller_folder/action

2.1 Создайте Actionкласс контроллера :

Приложение / код / ​​NameSpace / модуль / контроллер / Test / action.php

namespace NameSpace\Module\Controller\Test;

class Action extends \Magento\Framework\App\Action\Action
{
    public function execute()
    {
        $request = $this->getRequest();
        //EXECUTE YOUR LOGIC HERE
    }
}

2.2 Зарегистрируйте маршрут для ваших контроллеров

Приложение / код / ​​NameSpace / модуль / и т.д. / adminhtml / routes.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
  <router id="standard">
     <route id="route" frontName="route">
        <module name="NameSpace_Module" />
    </route>
  </router>
</config>

2.3 Поскольку это будет использоваться при оформлении заказа, добавьте свой маршрут в список защищенных URL-адресов [РЕДАКТИРОВАТЬ]

Приложение / код / ​​NameSpace / модуль / и т.д. / di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Framework\Url\SecurityInfo">
        <arguments>
            <argument name="secureUrlList" xsi:type="array">
                <item name="route" xsi:type="string">/route/</item>
            </argument>
        </arguments>
    </type>
</config>

3. Добавьте файл javascript на страницу оформления заказа, используя следующий файл макета:

Приложение / код / ​​NameSpace / модуль / вид / интерфейс / расположение / checkout_index_index.xml

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
    <head>
       <link src="NameSpace_Module::js/payment-method-trigger.js"/>
    </head>
</page>

4. В этом сценарии вы можете просто добавить функцию для отправки запроса на публикацию ajax каждый раз при нажатии на вкладку способа оплаты.


Лучший метод - нокаут: подписка на наблюдаемые

Лучший способ инициировать событие щелчка без расширения / переопределения основного файла или влияния на исходную функцию щелчка - это подписка наблюдаемого с помощью Knockout.

Метод 2 - Расширить класс JS [EDIT]

Также должен быть способ расширить начальный класс JS.

define([
    'NameSpace_Module/path/to/original/file', //JS FILE TO EXTEND
], function (originalFile) { //PASS AS A PARAMETER
    'use strict';

    return originalFile.extend({ //EXTEND
        //FUNCTIONS ADDED HERE WILL OVERRIDE FUNCTIONS
        //FROM ORIGINAL CLASS IF ALREADY EXISTS
        someFunction: {
            someLogic();
        },


    });
});

Способ 3 - переопределение select-payment-method.js

Игра с Knockout JS иногда может быть деликатной, и для целей этого ответа мы просто переопределим функцию, отвечающую за регистрацию метода оплаты, в предложении, которое вызывается функцией selectPaymentMethod. Возможно, это не самое элегантное решение по сравнению с использованием 100% Knockout JS, но оно должно работать как задумано, не затрагивая функциональность, если только будущее обновление Magento не помешает, изменив исходную функцию.

Чтобы лучше понять, вы можете найти функцию selectPaymentMethodв строке 139 этого файла:

Magento_Checkout / JS / просмотр / оплата / default.js

1. Теперь мы должны объявить переопределение нашей функции:

Приложение / код / ​​NameSpace / модуль / просмотр / интерфейс / requirejs-config.js

var config = {
    map: {
        '*': {
            'Magento_Checkout/js/action/select-payment-method':
                'NameSpace_Module/js/action/payment/select-payment-method'
        }
    }
};

2. Наконец, мы снова используем функцию, отвечающую за выбор способа оплаты, с небольшим дополнением, чтобы сделать наш вызов ajax!

Приложение / код / ​​NameSpace / модуль / вид / интерфейс / веб / JS / действие / оплаты / выбор-оплата-method.js

define(
    [
    'jquery',
    'uiComponent',
    'ko',
    'Magento_Checkout/js/model/quote',
    ], function ($, uiComponent, ko, quote) {
        'use strict';

        function () {
            $.ajax({
                showLoader: true,
                url: 'http://www.example.com/route/controller_folder/action',
                data: { action : 1, param : 2},
                type: "POST",
                dataType: 'json'
            }).done(function (data) {
                alert('Request Sent');
            });
        };

        return function (paymentMethod) {
            quote.paymentMethod(paymentMethod);
        }
});

Каждый раз, когда клиент нажимает на вкладку «Способ оплаты», ваш метод Javascript отправляет запрос post ajax вашему контроллеру, который выполнит код php с вашей логикой.

Это касается нескольких различных аспектов Magento 2. Хотя я хотел бы предоставить быстрое и простое решение вашего вопроса, именно так был построен Magento 2. Теперь большая часть логики реализована на стороне клиента и даже больше при приближении к кассовой системе.

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

ПРИМЕЧАНИЕ. Весь приведенный выше код не проверен.

ElGatito
источник
Realy хорошая информация
Pandurang
5

требовать

'Magento_Checkout/js/model/quote'

и наблюдать

quote.paymentMethod.subscribe(function(){console.log('yay')}, null, 'change');

так как есть много, чтобы наблюдать там

var billingAddress = ko.observable(null);
var shippingAddress = ko.observable(null);
var shippingMethod = ko.observable(null);
var paymentMethod = ko.observable(null);
var totals = ko.observable(totalsData);
var collectedTotals = ko.observable({})
Антон С
источник
1
Спасибо! Прекрасно работает! Кроме того, если вы хотите проверить способ оплаты внутри функции, вы можете использовать первый аргумент , например: quote.paymentMethod.subscribe(function(method){console.log(method);}, null, 'change');
Сергей Учухлебау
0

Эти 2 можно попробовать соответственно

app/code/Magento/Payment/Model/Method/Adapter.php 
    payment_method_is_active
    $this->eventManager->dispatch(
        'payment_method_is_active',
        [
    'result' => $checkResult,
    'method_instance' => $this,
    'quote' => $quote
        ]);

Or 
    app/code/Magento/Payment/Model/Method/Adapter.php 
    payment_method_assign_data_
    $this->eventManager->dispatch(
        'payment_method_assign_data_' . $this->getCode(),
        [
    'method' => $this,
    'data' => $data
        ]);
суприя мишра
источник