Magento 1: почему некоторые методы-наблюдатели вызывают getEvent (), а некоторые нет?


8

Что-то, что я недавно заметил, и мне любопытно.

Пример 1: использование getEvent()

В Mage_Core_Model_Localeв setLocale()методе, событие отправляется:

Mage::dispatchEvent('core_locale_set_locale', array('locale'=>$this));

Наблюдатель от этого события bindLocale()изMage_Adminhtml_Model_Observer

public function bindLocale($observer)
{
    if ($locale=$observer->getEvent()->getLocale()) {
        if ($choosedLocale = Mage::getSingleton('adminhtml/session')->getLocale()) {
            $locale->setLocaleCode($choosedLocale);
        }
    }
    return $this;
}

Итак, как вы можете видеть, чтобы получить локаль, мы сначала вызываем getEvent()наблюдателя.

Пример 2: без getEvent()

В Mage_Wishlist_Block_Customer_Wishlist_Item_Optionsв __construct()методе, событие отправляется:

Mage::dispatchEvent('product_option_renderer_init', array('block' => $this));

Поэтому мы согласны с тем, что один и тот же синтаксис используется для примеров 1 и 2.

Тем не менее, наблюдатель для этого второго примера initOptionRenderer()изMage_Bundle_Model_Observer

public function initOptionRenderer(Varien_Event_Observer $observer)
{
    $block = $observer->getBlock();
    $block->addOptionsRenderCfg('bundle', 'bundle/catalog_product_configuration');
    return $this;
}

И, как вы можете видеть, чтобы получить блок, мы не вызываем getEvent()наблюдателя

Вопрос

  • Почему getEvent()метод вызывается в примере № 1? Или почему getEvent()не вызывается в примере № 2?
  • Какова цель getEvent()метода?
  • Где следует использовать getEvent()и где не следует его использовать?

Ответы:


7

Это, вероятно, имеет исторические причины, выходящие за рамки версии 1.0.

Varien_EventОбъект является логическим местом , чтобы содержать параметры для конкретного события, но так как Magento проходит Varien_Observerобъект для всех методов наблюдателей, ярлык параметры доступа смысла (и это было там по крайней мере с 1.1).

На самом деле я не вижу значения в двух разных объектах, как они используются сегодня .

Но это явно не планировалось с самого начала. В методе задаются Mage::addObserver()не только имена событий и наблюдателей и статические аргументы из <args>узла XML, но и обратный вызов:

$observer->setName($observerName)->addData($data)->setEventName($eventName)->setCallback($callback);

Таким образом, наблюдатели могут отправлять себя, с $observer->dispatch($event). В этом случае наблюдатели не будут иметь данных о себе, и вам потребуется использовать их getEvent()для доступа к ним. Но метод нигде не используется, поэтому на практике это не имеет значения.

Если вы хотите попрактиковаться в некоторой программной археологии и копать больше, вы найдете больше мертвого кода, который намекает на оригинальные идеи, которые никогда не превращались в конечный продукт, например Varien_Event_Observer_Collection.


Спасибо. Собирался упомянуть об «исторических» аспектах. Похоже, вы сделали это для нас :)
Rajeev K Tomy

8

Ясно одно.

Звоню $observer->getEvent()->getSomething()и $observer->getSomething()возвращаю тоже самое.

Посмотрите на Mage_Core_Model_App::dispatchEventметод.

В какой-то момент у вас есть, $event = new Varien_Event($args);где $argsаргументы передаются в dispatchEventметод.
И Varien_Eventрасширяется, Varien_Objectчтобы вы могли волшебным образом получить доступ к элементам $argsиз Varien_Eventэкземпляра.

но есть и эта линия, $observer->addData($args);где $argsте же вещи, что и выше.

Varien_Event_Observerтакже расширяется, Varien_Objectтак что это позволяет вам магическим образом получить доступ к элементам $argsчерез объект Observer.

Вывод:

$_dataЧлен в классе Observer и класса Event содержат вид тех же вещей. У наблюдателя есть еще несколько других полей. как event, event_name.

Допустим, $argsвыглядит так:

array(
   'some_arg' => 'someArg',
   'other_arg' => 'otherArg',
)

При отправке $_dataсобытия объект в событии будет выглядеть так:

array(
   'some_arg' => 'someArg',
   'other_arg' => 'otherArg',
   'name' => 'event name here'
)

и в классе Observer будет выглядеть так:

array(
   'some_arg' => 'someArg',
   'other_arg' => 'otherArg',
   'event_name' => 'event name here',
   'event' => instance of Varien_event,
   'callback' => ..., 
   'name' => 'observer name here'
)

Но я не могу ответить, почему существует такая непоследовательность.
Я могу только предположить, что код был написан двумя разными разработчиками.
Если оно чего-то стоит, я всегда пользуюсь $observer->getEvent()->getSomething().

[РЕДАКТИРОВАТЬ]

Почему метод getEvent () вызывается в примере № 1? Или почему getEvent () не вызывается в примере # 2?

Недостаток согласованности

Какова цель метода getEvent ()?

Varien_EventОбъект должен быть объектом обертки над аргументами , переданных к наблюдателю

Где следует использовать getEvent () и где его нельзя использовать? Используйте их как хотите. Вы будете получать один и тот же результат все время.


Получил объяснение относительно непоследовательности, см. Мой ответ
Рафаэль в Digital Pianism

Я всегда предпочитаю $observer->getEvent()захватывать любые данные в обозревателе. Я знаю, что мы можем получить данные $observerнапрямую. Но я не делаю этого, потому что я всегда чувствую, что внедрение объекта Varien_Eventочень специфично для хранения данных события. Следовательно, я всегда зависим от объекта события. Я чувствую, что это правильный подход.
Раджив К Томи

@RajeevKTomy посмотри мой ответ, на самом деле нет смысла использовать, getEvent()за исключением случаев, когда тебе нужно имя события ИЛИ хочешь быть совместимым с Magento 1.0
Рафаэль на Digital Pianism

3

Объяснение относительно отсутствия согласованности.

По словам Винай и что Виталий Коротун сказал ему в какой-то момент:

getEvent()это наследие. Вернувшись в Magento 1.0 дней, данные события не могли быть получены непосредственно от наблюдателя.

Поэтому, если вам не нужно получать event_nameи не слишком беспокоиться о совместимости вашего кода с Magento 1.0, вы можете обойтись без него getEvent().

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.