2017-11-28 31 views
0

다 대다수의 관계를 나타내는 다중 선택 양식 요소에서 값을 미리 선택할 수 없습니다.ZF2 다중 선택 서식 사전 선택 값 ManyToMany

내 모델에는 적절한 데이터가 있습니다. 올바른 CampsTypes를 포함하지만 올바른 선택 항목을 미리 선택하기 위해 다중 선택을 사용할 수없는 형태의 ArrayCollection입니다.

관리자 모델

/** 
* @var ArrayCollection CampsTypes $campstypes 
* 
* @ORM\ManyToMany(targetEntity="CampsTypes", inversedBy="admins", cascade={"persist"}) 
* @ORM\JoinTable(name="campstypes_admins", 
*  joinColumns={@ORM\JoinColumn(name="admins_id", referencedColumnName="id")}, 
*  inverseJoinColumns={@ORM\JoinColumn(name="campstypes_id", referencedColumnName="id")} 
*  ) 
*/ 
private $campstypes; 

마침내 여기

 [ 
      'type' => 'DoctrineModule\Form\Element\ObjectSelect', 
      'name' => 'campTypes', 
      'required' => false, 
      'options' => [ 
       'object_manager' => $this->getServiceLocator()->get(EntityManager::class), 
       'target_class' => CampsTypes::class, 
       'property'  => 'title', 
       'label'   => 'Type de camps autorisés', 
       'instructions' => 'Ne rien sélectionner si edition d\'un super admin', 

      ], 
      'attributes' => [ 
       'class' => '', 
       'multiple' => 'multiple', 
      ] 
     ], 

를 수행하고

/** 
* @var ArrayCollection Admins $admins 
* 
* @ORM\ManyToMany(targetEntity="Admins", mappedBy="campstypes", cascade={"persist"}) 
*/ 
private $admins; 

가 그럼 난 내 양식을 선택 요소를 정의 CampsType 모델은을받을 수있는 내 작업입니다 양식

protected function saveAdmin(Admins &$admin, &$form, &$msg) 
{ 
    $em = $this->getEntityManager(); 
    /** @var CampTypesService $serviceCampTypes */ 
    $serviceCampTypes = $this->getServiceLocator()->get(CampTypesService::class); 

    $form->bind($admin); 

    if ($this->getRequest()->isPost()) { 
     $data = $this->getRequest()->getPost(); 
     if (empty($data['password'])) { 
      $form->remove('password'); 
     } 
     $form->setData($data); 
     if ($form->isValid()) { 
      if (isset($data['campTypes'])) { 
       $ids = $form->get('campTypes')->getValue(); 
       $campsTypes = new ArrayCollection($serviceCampTypes->getCampTypesByIds(array_values($ids))); 
       foreach ($campsTypes as &$campsType) { 
        /** @var CampsTypes $campsType*/ 
        $campsType->addAdmin($admin); 
       } 
       $admin->setCampTypes($campsTypes); 
      } 
      $em->persist($admin); 
      $em->flush(); 
      $msg = 'Sauvegarde des données effectuée'; 
      return; 
     } 
    } 

    return; 
} 

나는 해결책을 찾고 있습니다.
내가 뭘 잘못하고 있는지 알기!

답변

0

그래서 나는 그것을 만들었다!

기본적으로 내 주요 문제는 양식의 필드 이름에 적절한 Doctrine 명명 규칙을 사용하지 않는다는 것입니다.

그래서 DB가 교리 엔티티로 리버스 엔지니어링 되어야만 작동하지 않는 부분을 이해할 수있었습니다. 또한 전체 shabang이 작동하도록 양 끝 (관리자의 camptype 및 camptypse의 관리자)에 모델을 설정하십시오.

관리 양식 :

[ 
    'type' => ObjectSelect::class, 
    'name' => 'campstypes', 
    'required' => false, 
    'options' => [ 
     'object_manager' => $this->getServiceLocator()->get(EntityManager::class), 
     'target_class' => CampsTypes::class, 
     'property'  => 'title', 
     'label'   => 'Type de camps autorisés', 
     'instructions' => 'Ne rien sélectionner si edition d\'un super admin', 

    ], 
    'attributes' => [ 
     'class' => '', 
     'multiple' => 'multiple', 
    ] 
], 

관리 컨트롤러 : 제대로 내 양식의 필드와 모델의 이름을 변경하고 설정하여 그래서

protected function saveAdmin(Admins &$admin, &$form, &$msg) 
{ 
    $em = $this->getEntityManager(); 
    /** @var CampTypesService $serviceCampTypes */ 
    $serviceCampTypes = $this->getServiceLocator()->get(CampTypesService::class); 

    $form->bind($admin); 

    if ($this->getRequest()->isPost()) { 
     $data = $this->getRequest()->getPost(); 
     if (empty($data['password'])) { 
      $form->remove('password'); 
     } 
     $form->setData($data); 
     if ($form->isValid()) { 
      if (isset($data['campstypes'])) { 
       $ids = $form->get('campstypes')->getValue(); 
       $campsTypes = new ArrayCollection($serviceCampTypes->getCampTypesByIds(array_values($ids))); 
       foreach ($campsTypes as &$campsType) { 
        /** @var CampsTypes $campsType*/ 
        $campsType->addAdmin($admin); 
       } 
       $admin->setCampstypes($campsTypes); 
      } 
      $em->persist($admin); 
      $em->flush(); 
      $msg = 'Sauvegarde des données effectuée'; 
      return; 
     } 
    } 

    return; 
} 

다음은 작업 클래스입니다 관계의 양쪽 모델에서 데이터를 얻었습니다.

0

read this? ObjectSelect 양식 요소 대신 ObjectMultiCheckbox을 찾고 있다는 느낌이 들었습니다. 내 자신의 코드에서

하나를 선택에 대한 사용 (사용 사례 : 세트/다른 개체에 대한 기본 통화를 변경) 여러에 대한

$this->add([ 
    'type' => ObjectSelect::class, 
    'required' => true, 
    'name' => 'defaultCurrency', 
    'options' => [ 
     'object_manager' => $this->getEntityManager(), 
     'target_class' => Currency::class, 
     'property'  => 'id', 
// Use these commented lines if you wish to use a Repository function ('name' => 'repositoryFunctionName') 
//  'is_method'  => true, 
//  'find_method' => [ 
//   'name' => 'getEnabledCurrencies', 
//  ], 
     'display_empty_item' => true, 
     'empty_item_label' => '---', 
     'label' => _('Default currency'), 
     'label_attributes' => [ 
      'class' => '', 
      'title' => _('Default currency'), 
     ], 
     'label_generator' => function ($targetEntity) { 
      /** @var Currency $targetEntity */ 
      return $targetEntity->getName(); // Generates option text based on name property of Entity (Currency in this case) 
     }, 
    ], 
]); 

사용은 (사용을 선택 사례 : 사용자에게 역할 추가/제거 (복수)

$this->add([ 
    'name' => 'roles', 
    'required' => false, 
    'type' => ObjectMultiCheckbox::class, 
    'options' => [ 
     'object_manager' => $this->getEntityManager(), 
     'target_class' => Role::class, 
     'property'  => 'id', 
     'display_empty_item' => true, 
     'empty_item_label' => '---', 
     'label' => _('Roles'), 
     'label_generator' => function ($targetEntity) { 
      /** @var Role $targetEntity */ 
      return $targetEntity->getName(); 
     }, 
    ], 
]); 

참고 사항 : 실제로 공장을 더 많이 사용해야합니다. 수업 코드 전체에서 ServiceLocator을 사용하는 것을 보았으므로 공장을 통해 필요를 주입하여 피할 수 있습니다.


자세한 정보가 필요하면 과거 질문도 참조하십시오. 나는 당신이 찾고있는 것과 비슷한 것을 시작하는 꽤 많은 것을 가지고있었습니다. 저만의 솔루션 중 상당수를 스스로 관리하고 솔루션을 깊이있게 설명하려고 노력했습니다.

+0

감사합니다. 나는 빨간색이 아니었지만 실제로는 ObjectSelect를 사용하려고합니다. 실제로 해결책을 찾았으므로 해답을 게시 할 것입니다. – ddattee

+0

내가 아는 공장에 관해서는 공장을 만들어야하지만 Magento 2와 Symfony에서 약간의 의존성이 생겨 나는 모든 클래스의 공장을 매우 비효율적으로 만드는 것으로 나타났습니다. 또한 ZF2가 출시되었을 때이 프로젝트가 시작되었으므로 리콜로 멘 테이션이 서비스 위치 지정자를 사용하는 것이었지만 어느 시점에서 직접 정리해야합니다. – ddattee