Passa i dati a getChildHtml () o chiama il metodo sul blocco figlio


12

Voglio essere in grado di passare i dati alla chiamata getChildHtml (). Il motivo è che l'output del blocco dipende da un tipo di prodotto. Quindi voglio passare il prodotto a getChildHtml in modo che possa decidere l'output.

Lo sto facendo dentro template/checkout/cart/item/default.phtml.

Idealmente, la chiamata sarebbe simile a:

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

Quindi il mio blocco può ottenere il tipo di prodotto dall'articolo e visualizzare l'output corretto.

Dal momento che non è assolutamente possibile passare questi dati a getChildHtml- in quale altro modo è possibile ottenere questo tipo di comportamento senza dover riscrivere il blocco principale

Le due soluzioni che ho attualmente sono le seguenti (né molto interessanti):

1 - Crea un helper e accedi all'output html tramite l'helper invece di lasciare che un blocco e un modello lo rendano ala $this->helper('my_module')->getItemHtml($_item);

2 - Accedi al blocco figlio e impostaData su di esso all'interno del modello:

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

Penso in termini di architettura Magento, il numero 2 è il minore dei due mali, ma è dannatamente brutto guardare dentro un modello.


È possibile invece fornire i "dati" nel registro o nella sessione utilizzati dal blocco figlio? Lo stai usando in un iteratore? Qual è il caso d'uso?
Filwinkle,

Non credo che il registro possa essere d'aiuto in quanto l'output desiderato dipende dal tipo di prodotto degli articoli carrello. Quindi questo deve essere passato al blocco in qualche modo in modo che i dati corretti possano essere emessi. Il caso d'uso mostra alcune informazioni aggiuntive sull'articolo del carrello, ma dipende dal tipo di prodotto
Marty Wallace,

È possibile creare attributi del tipo di prodotto - forse si creano attributi diversi in base ai tipi di prodotto? Se preferisci creare il tuo blocco, possiamo sicuramente consigliare in quella direzione, ma qui potrebbero esserci altre vincite integrate che sto cercando di annusare ...
Philwinkle,

Bene, è un attributo a livello di prodotto a cui sto accedendo, ma il modo in cui viene visualizzato dipende dal tipo di prodotto. Un prodotto raggruppato renderà lo stesso attributo in modo leggermente diverso rispetto a un prodotto semplice. Sto usando un blocco e un modello per ogni diverso aspetto dell'output
Marty Wallace,

Ho aggiornato la mia domanda con alcune idee che sto contemplando, ma non mi sento a mio agio al 100%
Marty Wallace,

Risposte:


3

È possibile aggiungere un metodo sul blocco padre per recuperare il figlio in base al tipo di prodotto (ho visto questo tipo di logica un paio di volte nel core o qualcosa di simile):

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();

Tuttavia, vedendo come modifichi il layout xml per aggiungere blocchi secondari, potresti essere interessato a come Magento ha deciso di lavorare con il markup di rendering a seconda dei tipi di prodotto in Mage_Sales_Block_Items_Abstract::getItemHtml()e Mage_Checkout_Block_Cart_Abstract::getItemHtml().


Questo metodo ignora la struttura del layout e produce blocchi strettamente accoppiati (come tutto in Magento ...)
Victor Schröder,

12

La soluzione di cui sopra non funzionerà se si visualizza il blocco figlio in foreachloop.

Per questo è necessario utilizzare il seguente codice:

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

In child.block è possibile utilizzare $this->getMyData()per ottenere i dati. Usando questa strategia il blocco figlio otterrà sempre i dati più recenti dal genitore.

Il secondo parametro di getChildHtml()è $useCache. L'impostazione su false impedisce la memorizzazione nella cache del primo output e impone nuovamente il rendering del figlio.


4

Un blocco che può ricevere dati è chiamato widget ; sebbene ciò possa essere fatto tramite più definizioni di blocco (basate sulle proprietà di $_item).

Magento fa qualcosa di molto simile nel core caricando il blocco del metodo di pagamento basato sul codice funzione del metodo:

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

Puoi fare lo stesso con questo pseudo-codice:

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

Tutto ciò che richiederebbe sarebbe quello di avere un tipo di blocco diverso per ogni tipo di prodotto - bundle, simple, configurable, virtual, grouped. Non così male, davvero.

Se vuoi davvero usare un widget - sarebbe qualcosa per l'effetto della tua seconda idea nella tua domanda modificata:

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

Creare un widget probabilmente al di fuori dell'ambito di questa risposta, ma non è tremendamente difficile e ha il vantaggio di poter essere riproposto per blocchi CMS, anche se per il tuo caso d'uso non penso che sia applicabile.

Per ulteriori informazioni sulla creazione di un widget:

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


Non sono convinto al 100% che questo sia un buon approccio a questo, che non ho accettato la risposta.
Marty Wallace,

1
Solo un blocco widget può ricevere dati? Cosa intendi? Tutti i blocchi possono ricevere dati. Un widget è qualcosa di diverso in termini di Magento.
nevvermind

Non ho mai detto che non potevano; Sto dicendo che, per definizione, un widget richiede l'inserimento di dati per visualizzare qualcosa in modo condizionale.
Filwinkle,

0

Per Magento 2, puoi usare

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

Per ottenere i dati,

$block->getMyData();

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.