首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >嵌入表单集合错误:无法确定属性的访问类型

嵌入表单集合错误:无法确定属性的访问类型
EN

Stack Overflow用户
提问于 2017-02-15 18:26:47
回答 8查看 4.9K关注 0票数 19

根据this tutorial的说法,我正在尝试将Tag表单集合嵌入到Service表单中。TagService实体具有多对多关系。

窗体呈现正确。但是当我提交表单时,我会收到

错误。我不明白为什么不通过调用addTag()方法将新的Tag对象添加到Service类中。

ServiceType

代码语言:javascript
复制
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('title', TextType::class, array(
            'label' => 'Title'
        ))
    ;

    $builder->add('tagList', CollectionType::class, array(
        'entry_type' => TagType::class,
        'allow_add' => true,
        'allow_delete' => true,
        'by_reference' => false
    )));
}

服务类

代码语言:javascript
复制
{
....
 /**
 * @ORM\ManyToMany(targetEntity="Tag", mappedBy="serviceList",cascade={"persist"})
 */ 
private $tagList;

/**
 * @return ArrayCollection
 */
public function getTagList()
{
    return $this->tagList;
}

/**
 * @param Tag $tag
 * @return Service
 */
public function addTag(Tag $tag)
{
    if ($this->tagList->contains($tag) == false) {
        $this->tagList->add($tag);
        $tag->addService($this);
    }
}

/**
 * @param Tag $tag
 * @return Service
 */
public function removeTag(Tag $tag)
{
    if ($this->tagList->contains($tag)) {
        $this->tagList->removeElement($tag);
        $tag->removeService($this);
    }
    return $this;
}
}

标签类

代码语言:javascript
复制
 {
  /**
 * @ORM\ManyToMany(targetEntity="Service", inversedBy="tagList")
 * @ORM\JoinTable(name="tags_services")
 */
private $serviceList;
 /**
 * @param Service $service
 * @return Tag
 */
public function addService(Service $service)
{
    if ($this->serviceList->contains($service) == false) {
        $this->serviceList->add($service);
        $service->addTag($this);
    }
    return $this;
}

/**
 * @param Service $service
 * @return Tag
 */
public function removeService(Service $service)
{
    if ($this->serviceList->contains($service)) {
        $this->serviceList->removeElement($service);
        $service->removeTag($this);
    }
    return $this;
}
 }

ServiceController

代码语言:javascript
复制
  public function newAction(Request $request)
{
    $service = new Service();
    $form = $this->createForm('AppBundle\Form\ServiceType', $service);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        $em = $this->getDoctrine()->getManager();
        $em->persist($service);
        $em->flush();

        return $this->redirectToRoute('service_show', array('id' => $service->getId()));
    }

    return $this->render('AppBundle:Service:new.html.twig', array(
        'service' => $service,
        'form' => $form->createView(),
    ));
}
EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2017-02-21 00:48:42

你能试着从这个URL实现代码吗?

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#owning-and-inverse-side-on-a-manytomany-association

首先,请尝试更改映射/反面,并从Tag::addService方法中删除$service->addTag($this);

票数 4
EN

Stack Overflow用户

发布于 2017-02-25 04:17:37

简短版本:

我刚刚遇到了这个问题,并通过为受影响的属性添加一个setter来解决它:

无法确定属性"tagList"的访问类型

代码语言:javascript
复制
public function setTagList(Array $tagList)
{
    $this->tagList = $tagList;
}

长版本:

该错误消息表明Symfony正在尝试修改对象的状态,但由于其类的设置方式,无法确定如何实际进行更改。

Taking a look at Symfony's internals,我们可以看到Symfony给了你5次机会让你访问它,并按从上到下的顺序挑选最好的一个:

  1. 带有一个参数的名为setProperty()的设置器方法:

这是Symfony检查的第一件事,也是实现这一点的最明确的方法。据我所知,这是最佳实践:

代码语言:javascript
复制
class Entity {

    protected $tagList;

    //...

    public function getTagList()
    {
        return $this->tagList;
    }

    //...
}

  1. 通过一个参数将getter和setter组合在一个方法中:

为了获得对象的状态,Symfony也会访问这个方法,这一点很重要。由于这些方法调用不包含参数,因此此方法中的参数必须是可选的。

代码语言:javascript
复制
class Entity {

    protected $tagList;

    //...

    public function tagList($tags = null)
    {
        if($reps){
            $this->tagList = $tags;
        } else {
            return $this->tagList;
        }
    }

    //...
}

  1. 将受影响的属性声明为公共:

类实体{公共$tagList;//...此处还有其他属性}

  • A __set魔法方法:

这将影响所有属性,而不仅仅是您想要的属性。

代码语言:javascript
复制
class Entity {

    public $tagList;

    //...

    public function __set($name, $value){
        $this->$name = $value;
    }
    //...
}

  1. A __call magic method (在某些情况下):

我无法确认这一点,但内部代码表明,当在PropertyAccessor的构造上启用magic时,这是可能的。

只需要使用上面的一种策略。

票数 3
EN

Stack Overflow用户

发布于 2017-02-18 01:51:15

也许问题是Symfony无法访问该属性?

如果查看异常抛出位置( PropertyAccessor类中的writeProperty方法),就会发现可以抛出该异常:

如果属性不存在或不是公共属性,则为

在教程中,您提到了它有属性$tags和方法addTag。我在这里只是猜测,但可能有一种约定,它试图调用一个名为add($singularForm)的方法,但这对您来说是失败的,因为属性为tagList,方法为addTag

我不是百分之百确定,但你可以尝试调试,通过在Symfony方法中设置一个停止点来查看抛出它的原因。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42246686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档