Lulus data ke getChildHtml () atau metode panggilan di blok anak

12

Saya ingin dapat meneruskan data ke panggilan getChildHtml (). Alasannya, output dari blok tergantung pada jenis produk. Jadi saya ingin meneruskan produk ke getChildHtml sehingga dapat memutuskan output.

Saya melakukan ini di dalam template/checkout/cart/item/default.phtml.

Idealnya, panggilan akan terlihat seperti:

echo $this->getChildHtml('child_block_name', $_item);

Kemudian blok saya bisa mendapatkan jenis produk dari item dan menampilkan output yang benar.

Karena jelas tidak mungkin meneruskan data ini ke getChildHtml- bagaimana lagi jenis perilaku ini dapat dicapai tanpa harus menulis ulang blok inti

Dua solusi yang saya miliki saat ini adalah sebagai berikut (tidak terlalu menarik):

1 - Buat helper dan akses output html melalui helper alih-alih membiarkan blok dan template menjadikannya ala $this->helper('my_module')->getItemHtml($_item);

2 - Akses blok anak dan setData di dalamnya di dalam templat:

 $this->getChild('child_name')->setData('item', $_item);
 echo $this->getChildHtml('child_name')

Saya pikir dalam hal arsitektur Magento, nomor 2 adalah yang lebih rendah dari dua kejahatan, tetapi sangat jelek melihat ke dalam template.

Marty Wallace
sumber
Bisakah Anda memberikan 'data' dalam registri atau sesi yang digunakan oleh blok anak? Apakah Anda menggunakan ini di iterator? Apa gunanya?
philwinkle
Saya tidak berpikir registri akan membantu di sini karena output yang diinginkan tergantung pada jenis produk item keranjang. Jadi ini harus dilewatkan ke blok dalam beberapa cara sehingga data yang benar dapat di-output. Case use menampilkan beberapa info tambahan pada item keranjang, tetapi itu tergantung pada jenis produk
Marty Wallace
Anda dapat membuat atribut tipe produk - mungkin Anda membuat atribut berbeda berdasarkan jenis produk? Jika Anda lebih suka membuat blok Anda sendiri, kami tentu dapat menyarankan ke arah itu tetapi mungkin ada beberapa kemenangan built-in di sini yang saya coba
hirup
Ya, itu adalah atribut tingkat produk yang saya akses, tetapi cara itu ditampilkan tergantung pada jenis produk. Produk yang dikelompokkan akan membuat atribut yang sama sedikit berbeda dari mengatakan produk sederhana. Saya menggunakan blok dan templat untuk setiap rasa keluaran yang berbeda
Marty Wallace
Saya telah memperbarui pertanyaan saya dengan beberapa ide yang saya miliki yang saya renungkan tetapi tidak 100% nyaman dengan
Marty Wallace

Jawaban:

3

Anda dapat menambahkan metode pada blok induk untuk menjemput anak tergantung pada jenis produk (saya telah melihat jenis logika ini beberapa kali dalam inti atau sesuatu yang serupa):

class ParentBlock 
{
    public function getIntuitiveNameChild($item)
    {
        return $this->getChild("intuitive_child")
                    ->setProductType($item->getProductType()) 
                    // You can also decide the product type in this setter, in the Child block.
                    ->setItem($item);
    }

    public function getIntuitiveNameChildDinamically($item)
    {
        return $this->getChild("intuitive_child_" . $item->getProductType())
                    ->setItem($item); 
    }    
}

// parent tpl
// i suggest you avoid getChildHtml(), unless you're certain that methods won't need to be called from the tpl
echo $this->getIntuitiveNameChild($_item)
          // ->someOtherMethod()
          ->toHtml();

Namun, melihat bagaimana Anda memodifikasi tata letak xml untuk menambahkan blok anak-anak, Anda mungkin tertarik pada bagaimana Magento memutuskan untuk bekerja dengan rendering markup tergantung pada jenis produk di Mage_Sales_Block_Items_Abstract::getItemHtml()dan Mage_Checkout_Block_Cart_Abstract::getItemHtml().

nevvermind
sumber
Metode ini mem-bypass struktur tata letak dan menghasilkan blok yang dipasangkan dengan erat (seperti semua yang ada di Magento ...)
Victor Schröder
12

Solusi di atas tidak akan berfungsi jika Anda menampilkan blok anak dalam foreachloop.

Untuk itu Anda perlu menggunakan kode berikut:

<?php
foreach ($blocks as $block) {
    $this->getChild("child.block")->setData("my_data", $any_data);
    echo $this->getChildHtml('child.block', false);
}
?>

Di child.block Anda dapat menggunakan $this->getMyData()untuk mendapatkan data. Dengan menggunakan strategi ini, blok anak akan selalu mendapatkan data terbaru dari orang tua.

Parameter kedua getChildHtml()adalah $useCache. Menetapkannya ke false mencegah output pertama di-cache dan memaksa rendering anak lagi.

Arvind07
sumber
4

Blok yang dapat menerima data disebut widget ; meskipun ini dapat dilakukan melalui beberapa definisi blok (berdasarkan pada properti dari $_item).

Magento melakukan sesuatu yang sangat mirip dalam inti dengan memuat blok metode pembayaran berdasarkan kode pendek metode:

<dd>
    <?php echo $this->getChildHtml('payment.method.'.$_code) ?>
</dd>

Anda dapat melakukan hal yang sama dengan kode semu ini:

if($type = $_item->getTypeId()){
    $this->getChildHtml('my.block.' . $type);
}

Semua yang akan membutuhkan akan memiliki jenis blok yang berbeda untuk setiap jenis produk - bundle, simple, configurable, virtual, grouped. Tidak terlalu buruk, sungguh.

Jika Anda benar-benar ingin menggunakan widget - itu akan menjadi efek dari ide kedua Anda dalam pertanyaan yang diedit:

<?php
echo $this->getLayout()->createBlock('yourcompany/widget_class')->setType($_item->getTypeId())->toHtml();

Membuat widget mungkin di luar cakupan jawaban ini - tetapi itu tidak terlalu sulit, dan memiliki keuntungan karena dapat digunakan kembali untuk blok CMS, meskipun untuk kasus penggunaan Anda, saya tidak berpikir itu berlaku.

Untuk informasi lebih lanjut tentang cara membuat widget:

http://www.magentocommerce.com/knowledge-base/entry/tutorial-creating-a-magento-widget-part-1

Philwinkle
sumber
Saya tidak 100% yakin ini adalah pendekatan yang baik untuk ini yang saya belum menerima jawabannya.
Marty Wallace
1
Hanya blok widget yang dapat menerima data? Apa maksudmu? Semua blok dapat menerima data. Sebuah widget adalah sesuatu yang berbeda dalam hal Magento.
nevvermind
Saya tidak pernah mengatakan mereka tidak bisa; Menurut saya, menurut definisi, widget memerlukan input data untuk menampilkan sesuatu secara kondisional.
philwinkle
0

Sebab Magento 2, bisa Anda gunakan

<?php
foreach ($blocks as $block) {
    $block->getChildBlock("child.block")->setData("my_data", $any_data);
    echo $block->getChildHtml('child.block', false);
}
?>

Untuk mendapatkan data,

$block->getMyData();

Keyur Shah
sumber