Как структурировать модуль/виджет Ajax


Я довольно новичок в Magento и никогда раньше не пробовал ничего подобного, я все еще привыкаю к тому, как Magento делает вещи.

Я пытаюсь создать виджет, который добавит "Spraydeck finder" на любую страницу CMS. Для тех, кто не уверен, что я имею в виду, это точно такой же принцип, как и поиск автомобилей - просто подумайте о двух раскрывающихся списках, в которых вы сначала выбираете марку автомобиля (или в данном случае Каяк) - это действие заполняет второй раскрывающийся список доступными моделями из этого производителя, вы выбираете свою модель, и это действие отображает доступные продукты или информацию о конкретном транспортном средстве (или байдарке в моем случае).

На данный момент виджет отображается, и у меня есть первый выпадающий список, заполненный марками каяков, но, как вы увидите, когда вы прокрутите вниз, второй выпадающий список в настоящее время полностью обрабатывается в контроллере, я на 99% уверен, что это не "способ Magento", чтобы сделать это, должен ли я поместить все это в исходный блок или должен ли я использовать его для этого. Я использую контроллер для загрузки нового блока и вывода его через Ajax.Вызов обновителя? - очевидно, что как только модель выбрана, мне нужно снова пройти этот процесс, чтобы отобразить конкретную информацию для этого каяка.

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

В моем блоке у меня есть следующее:

class Dsingleton_Spraydecks_Block_Finder
    extends Mage_Core_Block_Template
    implements Mage_Widget_Block_Interface {
    /**
     * A model to serialize attributes
     * @var Varien_Object
     */
    protected $_serializer = null;

    /**
     * Initialization
     */
    protected function _construct()
    {
        $this->_serializer = new Varien_Object();
        parent::_construct();
    }

    /**
     * Produce links list rendered as html
     *
     * @return string
     */
    protected function _toHtml()
    {
        $html = '';
        $list = $this->getBrands();
        $this->assign('list', $list);

        return parent::_toHtml();
    }

    private function getBrands()
    {
        $brands_collection = Mage::getModel('dsingleton_spraydecks/finder')
            ->getCollection()
            ->distinct(true)
            ->addFieldToSelect('brand')
            ->load();

        $brand_list = array();
        $brand_list[] = '-- Please Select --';

        foreach ( $brands_collection as $brand )
        {
            $brand_list[] = $brand->brand;
        }

        return $brand_list;

    } }

В моем файле шаблона шаблона я имейте следующее:

<label for="finder">Brand: </label>
<select name="finder" id="sd-brand-select">
    <?php foreach ($list as $item) : ?>
        <option value="<?php echo $item ?>"><?php echo $item ?></option>
    <?php endforeach; ?>
</select>
<div id="sd-model"></div>
<script type="text/javascript">

    document.observe("dom:loaded", function() { 
        $$('#sd-brand-select').invoke('on', 'change', function(){

            var brand = this.getValue();
            if (brand != '-- Please Select --')
            {
                new Ajax.Updater('sd-model', '<?php echo Mage::getBaseUrl() ?>' + 'spraydecks/ajax/model/brand/' + brand, { method: 'post' });  
            }
        }); 
    });

</script>

И в моем контроллере у меня есть следующее:

class Dsingleton_Spraydecks_AjaxController extends Mage_Core_Controller_Front_Action {

    /**
     * Return the brands for a given manufacturer
     */    
    public function modelAction()
    {
        //check we have an ajax request
        $isAjax = Mage::app()->getRequest()->isAjax();

        if ($isAjax) {

            $this->loadLayout(false);
            $this->renderLayout();

            $brand = $this->getRequest()->getParam('brand');

            if($brand)
            {
                $boat_model_collection = Mage::getModel('dsingleton_spraydecks/finder')
                    ->getCollection()
                    ->addFieldToSelect('model')
                    ->addFieldToFilter('brand', $brand)
                    ->load();

                $model_list = array();
                $model_list[] = '-- Please Select --';

                foreach ( $boat_model_collection as $boat_model )
                {
                    $model_list[] = $boat_model->model;
                }

                $dropdown = '<option value="%s">%s</option>';

                echo '<label for="boat">Model: </label>';
                echo '<select name="finder" id="sd-brand-select">';

                 foreach ($model_list as $item){
                     echo sprintf($dropdown, $item, $item);
                 }

                echo '</select>';

            }
        }
    }
}
Author: David Manners, 2014-04-03

1 answers

Ваш подход - это на сто процентов способ Magento. Хотя мне не понравилось, что вы повторяете HTML в своем контроллере.

Поместите все ваши HTML-элементы в файл block.phtml. Экспортируйте JSON в свой контроллер, а затем в свой Javascript выполните:

document.observe("dom:loaded", function() { 
  $$("#sd-brand-select").invoke("on", "change", function(){

    var brand = this.getValue();
    if (brand != "-- Please Select --")
    {

       new Ajax.Request("<?php echo Mage::getBaseUrl() ?>" + "spraydecks/ajax/model/brand/" + brand, {
         method:"get",
         onSuccess: function(transport) {
           /* populate second select box with the results */
         },
         onFailure: function() { alert("Something went wrong..."); }
      });
  }); 
});
 0
Author: kbariotis, 2014-05-24 18:44:34