0

I'm facing a problem when calling __invoke() on an object. Is __invoke() method agnostic to instance variables? I need to call __invoke() directly on my templates due to some ZF2 injection to call $this->getView()->render(...) (otherwise getView() returns null) and I would like to have instance variables setted there. Any workaround?

See my code:

namespace Person\Person\View\Helper;


use Zend\View\Helper\AbstractHelper;

class PersonShowWidget extends AbstractHelper
{

    protected $model = null;

    public function __construct(array $options = null)
    {
        $this->parseOptions($options);
    }

    public function __invoke()
    {

        var_dump($this->model); //returns null
        return $this->getView()->render('person/show/show_widget', array(
                'title' => 'Cliente',
                'model' => $this->model,
            )
        );
    }

    public function setOptions(array $options = null)
    {
        $this->parseOptions($options);
    }

    protected function parseOptions(array $options = null)
    {
        if (!is_null($options) && is_array($options)) {
            if (isset($options['model'])) {
                $model = $options['model'];
                if (isset($model['id'])) {
                    $this->model['id'] = $model['id'];
                } else {
                    throw new \Exception;
                }
                if (isset($model['form'])) {
                    $this->model['form'] = $model['form'];
                } else {
                    throw new \Exception;
                }
            }
        }

        var_dump($this->model); //returns valid data

    }
}

I do have called the constructor with some options or the setOptions method before calling __invoke().

Thanks,

1 Answer 1

1

You have to initialize the view helper with a factory. In this way you can make sure the constructor is called before the __invoke method is called. And no..the __invoke() method is not agnostic to instance variables.

In the Module.php

public function getViewHelperConfig()
{
    return array(
        'factories' => array(
            'personShowWidget' => function ($helpers) {
                $array = array();
                $helper = new Person\Person\View\Helper\PersonShowWidget($array);
                return $helper;
            },
        )
    );
}

Or in the module.config.php

'view_helpers' => array
(
    'factories' => array(
        'personShowWidget' => function ($helpers) {
            $array = array();
            $helper = new Person\Person\View\Helper\PersonShowWidget($array);
            return $helper;
        },
    )
)

Performance-wise you'd better make a Factory class instead of a callable. More info: http://framework.zend.com/manual/2.0/en/modules/zend.module-manager.module-manager.html

Edit:

It seems like you using the ViewHelper wrongly. You don't have to create the instance by yourself. Just use the ViewHelper in the view. So why not just give the $options as parameter to the __invoke method?

public function __invoke(array $options = null)
{
    $this->setOptions($options);

    return $this->getView()->render('person/show/show_widget', array(
            'title' => 'Cliente',
            'model' => $this->model,
        )
    );
}

In the Controller pass the options array to the view:

return array(
    'options' => $options,
);

And call the ViewHelper in the view:

<?php echo $this->personShowWidget($this->options); ?>

Remember: In this way you don't need a Factory to init the ViewHelper. Just add it to the invokables.

module.config.php example:

'view_helpers' => array(
    'invokables' => array(
        'personShowWidget' => 'Person\Person\View\Helper\PersonShowWidget',
    ),
),
Sign up to request clarification or add additional context in comments.

3 Comments

Maybe I'm doing it conceptually wrong, what I'm trying to do is to create a new PersonShowWidget in the controller, configure it by the setOptions method and then display (echo) it in the view. Maybe getView() method returns null 'cause I'm not getting it throught the ViewManager inside the view?
I'm doing it the way that you mention now, the problem was that if i create the viewhelper in the controller, setView() was never called. Now I'm trying to render it in the controller 'cause I'd like to transform it into a modal and I would like to send the code only if the button gets pressed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.