2014-11-17 4 views
0

Я создал помощник представления для отображения последних объявлений из таблицы базы данных. Поскольку у меня есть разные типы объявлений, я хотел бы иметь возможность передавать переменную изнутри моего представления, где я вызываю помощника представления, чтобы показывать определенные Объявления.Zend Framework 2: передать переменную для просмотра помощника

Прошу прощения, что я не могу объяснить это лучше, но я все еще новичок в ZF2. Я добавлю Sourcecode и, надеюсь, это сделает его более понятным. Обратите внимание, что у меня есть исходный код из книги, в котором отображается Pizza случайным образом и сменил его, пока он не работал, чтобы показывать мои объявления. Я мог бы еще код в нем, который на самом деле не нужны, поэтому, пожалуйста, не удивляйтесь ... Хорошо здесь код:

1. Вид: index.html

<?php foreach ($this->latestAdvert() as $value){ ?> 
     <li><?php echo $value->getAdvertTitle();?></li> 
<?php }?> 

2. вид Helper: объявления \ вид \ Helper \ LatestAdvert.php

namespace Advert\View\Helper; 
use Zend\View\Helper\AbstractHelper; 

class LatestAdvert extends AbstractHelper 
{ 

    protected $random = null; 


    public function __construct($random) 
    { 
    $this->setLatestAdvert($random); 
    } 


    public function setLatestAdvert($random) 
    { 
    $this->random = $random; 
    } 


    public function getLatestAdvert() 
    { 
    return $this->random; 
    } 


    public function __invoke() 
    { 
    $latestAdverts = $this->getLatestAdvert(); 
    return $latestAdverts; 
    } 
} 

3. завод: Реклама \ вид \ Helper \ LatestAdvertFactory.php

namespace Advert\View\Helper; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class LatestAdvertFactory implements FactoryInterface 
{ 

    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $locator = $serviceLocator->getServiceLocator(); 
     $service = $locator->get('Advert\Service'); 
     $random = $service->fetchSingleByRandom(); 
     $helper = new LatestAdvert($random); 

     return $helper; 
    } 
} 

4. Услуга: Реклама \ Сервис \ LatestAdvertService .php

namespace Advert\Service; 

use Advert\Entity\Advert as AdvertEntity; 
use Doctrine\ORM\EntityManager; 
use Zend\ServiceManager\ServiceManager; 
use Zend\ServiceManager\ServiceManagerAwareInterface; 
use Zend\Debug\Debug; 

class LatestAdvertService implements ServiceManagerAwareInterface 
{ 

    /** 
    * Service manager. 
    * @var Zend\ServiceManager\ServiceManager 
    */ 
    private $serviceManager = null; 

    /** 
    * Sets service manager. 
    * @param Zend\ServiceManager\ServiceManager $serviceManager Service manager. 
    */ 
    public function setServiceManager(ServiceManager $serviceManager) 
    { 
    $this->serviceManager = $serviceManager; 
    } 

    /** 
    * Returns service manager. 
    * @return type 
    */ 
    public function getServiceLocator() 
    { 
    return $this->serviceManager; 
    } 


    public function fetchSingleByRandom() 
    {  
    // Get Doctrine entity manager. 
    $entityManager = $this->getServiceLocator() 
          ->get('doctrine.entitymanager.orm_default'); 
    $advertType = 'wanted'; // This should be removed 
    $random = $entityManager->getRepository('Advert\Entity\Advert') 
          ->findAdvertsByDate($advertType); 

    return $random; 
    } 
} 

5. Модуль: объявления \ module.php

public function getServiceConfig() 
{ 
    return array(
     'invokables' => array(
       'Advert\Service' => 'Advert\Service\LatestAdvertService', 
        ), 
    ); 
} 

public function getViewHelperConfig() 
{ 
    return array(
     'factories' => array(   
      'latestAdvert' => 'Advert\View\Helper\LatestAdvertFactory', 
     ), 

    ); 
} 

Как вы можете видеть в # 4 У меня есть переменная, называемая $ advertType. Я хочу установить переменную, когда я вызываю помощник представления в свой index.html, f.e. $ this-> latestAdvert ('wanted'), но как передать эту переменную через все мои файлы? Я просто не могу найти для этого решения. Кто-нибудь получил совет для меня, как его достичь? Заранее большое спасибо.

UPDATE!

Как указано в примере SenseException, инъекция локатора сервисов в службу является плохой практикой, и вместо этого я должен либо ввести репозиторий, либо менеджер сущностей в службу, теперь я разработал первое рабочее решение для диспетчера сущностей ,

Для этого я обновил 2 файлов: module.php и LatestAdvertService.php

# 5 module.php

public function getServiceConfig() 
{ 
    return array(
      'factories' => array(

        'Advert\Service' => function ($sl) { 
         $entityManager = $sl->get('doctrine.entitymanager.orm_default'); 
         $myService = new Service\LatestAdvertService(); 
         $myService->setEntityManager($entityManager); 
         //or you can set repository 
         //$repository = $entityManager->getRepository('Advert\Entity\Advert'); 
         //$myService->setRepository($repository); 
         return $myService; 
        }, 

4. Услуга: Реклама \ Service \ LatestAdvertService.PHP

namespace Advert\Service; 

use Advert\Entity\Advert as AdvertEntity; 
use Doctrine\ORM\EntityManager; 

class LatestAdvertService 
{ 


    public function setEntityManager(EntityManager $entityManager) 
    { 
    $this->entityManager = $entityManager; 
    } 

    public function setRepository(Repository $repository) { 
    $this->repository = $repository; 
    } 


    public function fetchSingleByAdvertType($advertType) 
    { 

    $random = $this->entityManager->getRepository('Advert\Entity\Advert')->findAdvertsByDate($advertType); 
// $random = $this->repository->findAdvertsByDate($advertType); 

    return $random; 
    } 
} 

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

Аргумент 1 передается Сейчас \ Service \ LatestAdvertService :: setRepository() должен быть экземпляр \ Сейчас Service \ AdvertisingRepository, экземпляр объявления \ репозиторий \ рекламный ресурс, вызванный в

Я буду продолжать находить решение для ввода и обновления хранилища при успешном завершении.

+1

Что касается вашего сообщения об ошибке («Аргумент 1 передан ...»), вам нужно добавить пространство имен репозитория в свой класс обслуживания, то есть «использовать рекламу/репозиторий \ Рекламуресурсы» и изменить подсказку типа из «Репозитория» к 'Рекламодателю' по методу' setRepository'. Без него «Репозиторий» будет считаться находящимся в текущем пространстве имен («Реклама \ Сервис \ Репозиторий») и, следовательно, ошибка. – AlexP

+0

Превосходно, что исправил проблему. Я действительно думал, что мне не нужно добавлять пространство имен репозитория, так как теперь я использую getRepository («Реклама \ Сущность/Реклама») в моем модуле.php, и когда я использовал этот код в своей службе раньше, у меня никогда не было пользы. .. namespace. Очень запутанно и все еще сложно учиться. Большое спасибо за Вашу помощь! – Luka

ответ

2

Как насчет этого решения:

namespace Advert\View\Helper; 

use Zend\ServiceManager\FactoryInterface; 
use Zend\ServiceManager\ServiceLocatorInterface; 

class LatestAdvertFactory implements FactoryInterface 
{ 

    public function createService(ServiceLocatorInterface $serviceLocator) 
    { 
     $locator = $serviceLocator->getServiceLocator(); 
     $service = $locator->get('Advert\Service'); 
     $helper = new LatestAdvert($service); 

     return $helper; 
    } 
} 

И, конечно, вспомогательный класс:

namespace Advert\View\Helper; 
use Zend\View\Helper\AbstractHelper; 

class LatestAdvert extends AbstractHelper 
{ 

    protected $service; 


    public function __construct($service) 
    { 
     $this->service = $service; 
    } 

    public function __invoke($advertType) 
    { 
     $latestAdverts = $this->service->fetchSingleByAdvertType($advertType); 
     return $latestAdverts; 
    } 
} 

И для службы:

public function fetchSingleByAdvertType($advertType) 
{ 
    $entityManager = $this->getServiceLocator() 
          ->get('doctrine.entitymanager.orm_default'); 

    $random = $entityManager->getRepository('Advert\Entity\Advert') 
          ->findAdvertsByDate($advertType); 

    return $random; 
} 

Я пытался сохранить свой код как можно ближе к вашему оригиналу, насколько это возможно, но, пожалуйста, ознакомьтесь с некоторыми предложениями относительно локатора обслуживания. Плохая практика заключается в том, чтобы внедрить локатор сервисов в службу, как в LastAdvertService. Поскольку вам нужен только репозиторий для вашего сервиса, просто введите его в него. Если вам нужен диспетчер сущностей в вашей службе, добавьте его вместо этого. Ваши собеседники будут благодарны вам.

+0

Большое спасибо SenseException, он работает! Я был близок к тому, чтобы сдаться, потому что я не мог заставить его работать. Теперь я пытаюсь понять ваше предложение и буду искать лучшее решение, даже если я чувствую, что никогда не хочу касаться этого кода снова, после того, как он наконец работает :) Правильно ли я должен вставить репозиторий в модуль .php? Я обновлю свой код выше, когда я его заработаю. Еще раз спасибо ! – Luka

+0

BTW: Поскольку LastAdvert теперь получает Сервис в свой конструктор, вы можете избавиться от фабрики и сделать LastAdvert самой услугой, если хотите. – SenseException

+0

Будет ли это лучшим способом или мой путь в порядке? Я думал, что теперь это четкое разделение, но я хотел бы иметь «лучший» способ, особенно когда я все еще учусь, такие предложения, как твои, фантастичны. Я видел этот тип настройки много раз, службу, фабрику, даже если я все еще пытаюсь понять все ... – Luka

Смежные вопросы