0

I successfully added a custom view helper with the following configuration:

https://gist.github.com/webdevilopers/b22f7471fd2b8d60cdea#file-module-php

The view helper has a custom variable named foo:

https://gist.github.com/webdevilopers/b22f7471fd2b8d60cdea#file-abstractformautocomplete-php

As I mentioned this setup works fine as long as I have only a single element using the view helper.

As soon as I add more than one form element the setFoo method gets only called once and the foo variable remains set throughout the following elements.

https://gist.github.com/webdevilopers/b22f7471fd2b8d60cdea#file-autocompleteform-php

I read about Shared Services in ZF2 - is this such a case? How can I prevent this behaviour?

Introduction to the Zend Framework 2 ServiceManager

By default, the ServiceManager assumes all services are shared, but you may specify a boolean false value here to indicate a new instance should be returned.

webDEVILopers
  • 1,886
  • 1
  • 21
  • 35

1 Answers1

2

You've basically answered your own question here. Services are shared by default, so the initial instance of your view helper is reused for subsequent calls unless you configure it otherwise. To do this, add the shared parameter to your view helper config (untested):

public function getViewHelperConfig()
{
    return array(
        'invokables' => array(
            'formelement'                  => 'Application\Form\View\Helper\FormElement',
            'formautocompletehidden'       => 'Application\Form\View\Helper\FormAutocompleteHidden'
        ),
        'shared' => array(
            'formelement' => false,
            'formautocompletehidden' => false
        ),
    );
}

Edit: as mentioned in the comments, this doesn't currently work for view helpers due to a bug in ZF2.

Tim Fountain
  • 33,093
  • 5
  • 41
  • 69
  • Thanks for the quick answer, @Tim Fountain. Your solution is obviously correct. I found a similar answer here: http://stackoverflow.com/questions/21272055/multiple-instances-of-view-helper-plugin - Unfortunately it does not work. Is there a global parameter to set to make the service manager "allow" setting the `shared` entry? – webDEVILopers Jun 25 '14 at 13:31
  • When you say it doesn't work, do you mean the view helpers are still not being shared? Presumably your actual code isn't just setting "foo", so what does it really do and how are you testing whether or not the shared thing works? – Tim Fountain Jun 25 '14 at 13:38
  • As you can see the setFoo() method checks if $foo has already been set. When calling the view template with the two elements using the view helper I only get the first echo, the second time it is not called. Maybe there is some in-between class since I am passing the $element to that method. If the $element e.g. is a formText element should I add a shared=false entry for it too? – webDEVILopers Jun 25 '14 at 13:45
  • I should point out that the only reason I need to set shared service to false is the fact that methods like getFoo() check for an existing variable $foo to avoid unneccessary usage of setters. It's not critical yet because I could simply comment out the condition. I thought this was a good approach and it seemed like official #zf2 form elements did something similar: if ($this->elementHelper) { return $this->elementHelper; } – webDEVILopers Jun 25 '14 at 13:53
  • @samsonasik has posted an issue on this: https://github.com/zendframework/zf2/issues/4221 – webDEVILopers Jun 25 '14 at 14:59
  • I just tested this out and you're right, it doesn't work. As mentioned on the issue you linked, this is a bug in ZF I think. – Tim Fountain Jun 25 '14 at 16:39
  • I've added my example: https://github.com/zendframework/zf2/issues/4221#issuecomment-47195693 - Maybe this is the same issue. – webDEVILopers Jun 26 '14 at 07:31