সিমফনি ২.৮, 3.0.০ এবং তারপরে বিল্ডফোর্মে () ডেটা পাস করা হচ্ছে


87

এই উত্তরটিতে প্রস্তাবিত হিসাবে আমার অ্যাপ্লিকেশনটি বর্তমানে কনস্ট্রাক্টর ব্যবহার করে আমার ফর্মের ধরণের ডেটা পাস করে । তবে সিমফনি ২.৮ আপগ্রেড গাইড পরামর্শ দেয় যে ফাংশনটিতে কোনও টাইপ উদাহরণ পাস করা অবমূল্যায়নcreateForm করা হয়েছে:

ফর্ম :: অ্যাড (), ফর্মবিল্ডার :: অ্যাড () এবং ফর্মফ্যাক্টরী :: তৈরি করুন * () পদ্ধতিগুলিকে অবহিত করা হয়েছে এবং সিমফনি 3.0 তে আর সমর্থন করা হবে না will পরিবর্তে প্রকারটির সম্পূর্ণ-যোগ্যতাসম্পন্ন শ্রেণীর নামটি পাস করুন।

Before:    
$form = $this->createForm(new MyType());

After:
$form = $this->createForm(MyType::class);

আমি পুরোপুরি যোগ্য শ্রেণীর নাম দিয়ে ডেটা পাস করতে পারছি না দেখে কী বিকল্প আছে?


4
আপনার কোন ধরণের ডেটা পাস করতে হবে? এটি কি এমন কিছু যা ইনজেকশন দেওয়া যায়?
সেরেড

4
আশা করি UPGRADE.md এর উন্নতি হবে: github.com/symfony/symfony/issues/18662
আলতাউস

উত্তর:


133

এটি আমাদের কিছু ফর্মও ভেঙে দিয়েছে। আমি বিকল্পগুলির সমাধানের মাধ্যমে কাস্টম ডেটা পাস করে এটি ঠিক করেছি।

আপনার ফর্ম টাইপ:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $this->traitChoices = $options['trait_choices'];

    $builder
        ...
        ->add('figure_type', ChoiceType::class, [
            'choices' => $this->traitChoices,
        ])
        ...
    ;
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'trait_choices' => null,
    ]);
}

তারপরে আপনি যখন আপনার নিয়ামকটিতে ফর্মটি তৈরি করেন, তখন এটি কনস্ট্রাক্টরের পরিবর্তে বিকল্প হিসাবে পাস করুন:

$form = $this->createForm(ProfileEditType::class, $profile, [
    'trait_choices' => $traitChoices,
]);

8
সবেমাত্র এই সমস্যাটি জুড়ে এসে একইরকম সমাধান করেছেন। আমি মনে করি যদি ডেটা প্রয়োজনীয় হয় এবং আপনি যদি কনস্ট্রাক্টরের সংজ্ঞাতে সাধারণত যে ধরণের ইঙ্গিতটি করতে চান তবে আপনি যদি আপনার কনফিগারঅ্যাপশনে () বিকল্পগুলি সমাধানের জন্য setRequired () এবং সেটএলয়েডটাইপস () পদ্ধতি ব্যবহার করতে পারেন পরিবর্তে setDephaults ()।
সারাহগ

4
আপনার ঠিক সেইটাই করা উচিত। :)
বার্নহার্ড শ্যাসেক

4
@ রৌবি আপনি একই কাজ করেন, আপনি কনফিগারঅ্যাপশন পদ্ধতিতে একটি বিকল্প নির্ধারণ করুন এবং তারপরে একটি ফর্ম ক্ষেত্র যুক্ত করার পরে এটি পাস করুন।
বার্ট ওয়েসেলিংক

4
আমিও এই পরিবর্তন নিয়ে খুশি নই। যদিও উত্তরের জন্য ধন্যবাদ।
অ্যাডামিন

4
ফর্মটাইপগুলি কারখানার মতো কাজ করে, তাদের উচিত রাষ্ট্রহীন। তাদের নির্মাণকারীর মাধ্যমে সার্ভিস ট্যাগ পদ্ধতির মাধ্যমে অন্য মানগুলি ইনজেকশন এটিকে রাজ্যময় করে তোলে state এইভাবে আপনার নিজের ফর্মের প্রকার তৈরির 1 টি অভিন্ন পদ্ধতি রয়েছে। বিকল্পগুলি সর্বদা নির্ধারক যুক্তির পরিবর্তে ব্যবহার করা হত। এই পরিবর্তনটি ডেক্স এবং ব্যবহারযোগ্যতার জন্য দুর্দান্ত।
যে কেউ

6

এখানে অন্য পদ্ধতির ব্যবহার করা যেতে পারে - ডেটা পুনরুদ্ধারের জন্য ইনজেকশন পরিষেবা।

  1. আপনার ফর্মটি পরিষেবা হিসাবে বর্ণনা করুন ( কুকবুক )
  2. ক্লাস গঠনে সুরক্ষিত ক্ষেত্র এবং নির্মাতা যুক্ত করুন
  3. আপনার প্রয়োজনীয় কোনও ডেটা পাওয়ার জন্য ইনজেকশনযুক্ত অবজেক্টটি ব্যবহার করুন

উদাহরণ:

services:
    app.any.manager:
        class: AppBundle\Service\AnyManager

    form.my.type:
        class: AppBundle\Form\MyType
        arguments: ["@app.any.manager"]
        tags: [ name: form.type ]

<?php

namespace AppBundle\Form;

use AppBundle\Service\AnyManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class MyType extends AbstractType {

    /**
     * @var AnyManager
     */
    protected $manager;

    /**
     * MyType constructor.
     * @param AnyManager $manager
     */
    public function __construct(AnyManager $manager) {
        $this->manager = $manager;
    }

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $choices = $this->manager->getSomeData();

        $builder
            ->add('type', ChoiceType::class, [
                'choices' => $choices
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults([
            'data_class' => 'AppBundle\Entity\MyData'
        ]);
    }

}

এটি ভাল, কিন্তু যখন সার্ভিস ম্যানেজারের কাছে তর্কটি উপলব্ধ না হয় তখন কাজ করবে না।
দৈত্যকৌড়ু

5

যদি কেউ ফর্ম.ফ্যাক্টরি পরিষেবা থেকে কোনও 'ক্রিয়েটনেমেডবিল্ডার' বা 'ক্রিয়েটনেমেড' ফাংশন ব্যবহার করে থাকে তবে কীভাবে ডেটা সেট করে এটি ব্যবহার করে সেভ করবেন সে সম্পর্কে স্নিপেট এখানে রয়েছে। আপনি 'ডেটা' ক্ষেত্রটি ব্যবহার করতে পারবেন না (সেই নালটি ছেড়ে দিন) এবং আপনাকে পাস করা ডেটা / সত্তাগুলিকে $optionsমান হিসাবে সেট করতে হবে ।

আমি সেটএলওয়েডটাইপস () এবং সেটরেকায়ার্ড () বিকল্পগুলি ব্যবহার সম্পর্কে @ সারাহগ নির্দেশাবলীও অন্তর্ভুক্ত করেছি এবং এটি দুর্দান্ত কাজ করছে বলে মনে হচ্ছে তবে আপনাকে প্রথমে সেটডাইফাইন্ড () দিয়ে ক্ষেত্রটি নির্ধারণ করতে হবে

ফর্মের ভিতরেও যদি আপনার ডেটা সেট করতে প্রয়োজন হয় তবে এটি 'ডেটা' ক্ষেত্রে যুক্ত করতে ভুলবেন না।

কন্ট্রোলারে আমি getBlockPrefix ব্যবহার করছি কারণ getName 2.8 / 3.0 এ অবহেলা করা হয়েছিল

নিয়ামক:

/*
* @var $builder Symfony\Component\Form\FormBuilderInterface
*/
$formTicket = $this->get('form.factory')->createNamed($tasksPerformedForm->getBlockPrefix(), TaskAddToTicket::class, null, array('ticket'=>$ticket) );

ফর্ম:

public function configureOptions(OptionsResolver $resolver)    {
    $resolver->setDefined('ticket');
    $resolver->setRequired('ticket');
    $resolver->addAllowedTypes('ticket', Ticket::class);

    $resolver->setDefaults(array(           
        'translation_domain'=>'AcmeForm',
        'validation_groups'=>array('validation_group_001'),
        'tasks' => null,
        'ticket' => null,
    ));
}

 public function buildForm(FormBuilderInterface $builder, array $options)   {

    $this->setTicket($options['ticket']);
    //This is required to set data inside the form!
    $options['data']['ticket']=$options['ticket'];

    $builder

        ->add('ticket',  HiddenType::class, array(
                'data_class'=>'acme\TicketBundle\Entity\Ticket',
            )
        )
...
}

5

এখানে সিমফনি ৩ ব্যবহার করে যে কেউ এম্বেড করা ফর্মটিতে ডেটা কীভাবে পাস করবেন তা এখানে প্রথমে @ সেকল উপরে বর্ণিত ঠিক করুন এবং তারপরে নিম্নলিখিতটি করুন:

আপনার প্রাথমিক ফর্মটাইপে

' Enter_options ' ব্যবহার করে এমবেড করা ফর্মটিতে ভেরটি পাস করুন

->add('your_embedded_field', CollectionType::class, array(
          'entry_type' => YourEntityType::class,
          'entry_options' => array(
            'var' => $this->var
          )))

আপনার এম্বেড করা ফর্মটাইপে

বিকল্পগুলি রিসলভারে বিকল্প যুক্ত করুন

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Yourbundle\Entity\YourEntity',
        'var' => null
    ));
}

আপনার বিল্ডফর্ম ফাংশনে পরিবর্তনশীল অ্যাক্সেস করুন। বিল্ডার ফাংশনের আগে এই পরিবর্তনশীলটি সেট করতে ভুলবেন না। আমার ক্ষেত্রে আমার নির্দিষ্ট আইডির উপর ভিত্তি করে বিকল্পগুলি ফিল্টার করা দরকার।

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $this->var = $options['var'];

    $builder
        ->add('your_field', EntityType::class, array(
          'class' => 'YourBundle:YourClass',
          'query_builder' => function ($er) {
              return $er->createQueryBuilder('u')
                ->join('u.entity', 'up')
                ->where('up.id = :var')
                ->setParameter("var", $this->var);
           }))
     ;
}

কম বিভ্রান্তি থাকতে - $ এই-> ভ্যার আপনার মানটি পাস করতে চান, বর্গ ভেরিয়েবলের অগত্যা নয়।
দারিয়াস.ভি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.