亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

表單

對(duì)一個(gè)Web開(kāi)發(fā)者來(lái)說(shuō),處理HTML表單是一個(gè)最為普通又極具挑戰(zhàn)的任務(wù)。Symfony整合了一個(gè)Form組件,讓處理表單變得容易起來(lái)。在本章,你將從零開(kāi)始創(chuàng)建一個(gè)復(fù)雜的表單,學(xué)習(xí)表單類庫(kù)中的重要功能。

Symfony的Form組件是一個(gè)獨(dú)立的類庫(kù),你可以在Symfony項(xiàng)目之外使用它。參考 Form組件文檔 以了解更多。

創(chuàng)建一個(gè)簡(jiǎn)單的表單 ?

假設(shè)你正在構(gòu)建一個(gè)簡(jiǎn)單的待辦事項(xiàng)列表,來(lái)顯示一些“任務(wù)”。你需要?jiǎng)?chuàng)建一個(gè)表單來(lái)讓你的用戶編輯和創(chuàng)建任務(wù)。在這之前,先來(lái)看看 Task 類,它可呈現(xiàn)和存儲(chǔ)一個(gè)單一任務(wù)的數(shù)據(jù)。

// src/AppBundle/Entity/Task.phpnamespace AppBundle\Entity; class Task{
    protected $task;
    protected $dueDate;     public function getTask()
    {
        return $this->task;
    }     public function setTask($task)
    {
        $this->task = $task;
    }     public function getDueDate()
    {
        return $this->dueDate;
    }     public function setDueDate(\DateTime $dueDate = null)
    {
        $this->dueDate = $dueDate;
    }}

這是一個(gè)原生的PHP對(duì)象類,因?yàn)樗鼪](méi)有和Symfony互動(dòng)也沒(méi)有引用其它類庫(kù)。它是非常簡(jiǎn)單的一個(gè)PHP對(duì)象類,直接解決了 程序中的 task (任務(wù))之?dāng)?shù)據(jù)問(wèn)題。當(dāng)然,在本章的最后,你將能夠通過(guò)HTML表單把數(shù)據(jù)提交到一個(gè) Task 實(shí)例,驗(yàn)證它的值,并把它持久化到數(shù)據(jù)庫(kù)。

構(gòu)建表單 ?

現(xiàn)在你已經(jīng)創(chuàng)建了一個(gè) Task 類,下一步就是創(chuàng)建和渲染一個(gè)真正的html表單了。在Symfony中,這是通過(guò)構(gòu)建一個(gè)表單對(duì)象并將其渲染到模版來(lái)完成的?,F(xiàn)在,在控制器里即可完成所有這些:

// src/AppBundle/Controller/DefaultController.phpnamespace AppBundle\Controller; use AppBundle\Entity\Task;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\Form\Extension\Core\Type\TextType;use Symfony\Component\Form\Extension\Core\Type\DateType;use Symfony\Component\Form\Extension\Core\Type\SubmitType; class DefaultController extends Controller{
    public function newAction(Request $request)
    {
        // create a task and give it some dummy data for this example
        // 創(chuàng)建一個(gè)task對(duì)象,賦一些例程中的假數(shù)據(jù)給它
        $task = new Task();
        $task->setTask('Write a blog post');
        $task->setDueDate(new \DateTime('tomorrow'));         $form = $this->createFormBuilder($task)
            ->add('task', TextType::class)
            ->add('dueDate', DateType::class)
            ->add('save', SubmitType::class, array('label' => 'Create Task'))
            ->getForm();         return $this->render('default/new.html.twig', array(
            'form' => $form->createView(),
        ));
    }}

這個(gè)例子說(shuō)明了如何直接在控制器中構(gòu)建你的form(表單)。后面的 創(chuàng)建表單類 中,你將使用一個(gè)獨(dú)立的類來(lái)構(gòu)建表單,這種方法被推薦,因?yàn)楸韱慰梢詮?fù)用。


創(chuàng)建表單不需要很多代碼,因?yàn)镾ymfony的表單對(duì)象是通過(guò)一個(gè)“form builder(表單生成器)”來(lái)創(chuàng)建的。form builder的目的是讓你編寫(xiě)簡(jiǎn)單的表單創(chuàng)建“指令”,而真實(shí)創(chuàng)建表單時(shí)的全部“重載”任務(wù)則交由builder完成。

本例中,你已經(jīng)添加了兩個(gè)字段到表單,即 taskdueDate 。對(duì)應(yīng)的是 Task 類中的 taskdueDate 屬性。你已為它們分別指定了FQCN(Full Quilified Class Name/完整路徑類名)的“類型”(如 TextType , DateType ),由類型決定為字段生成哪一種HTML表單標(biāo)簽(標(biāo)簽組)。

最后,你添加了一個(gè)帶有自定義label的提交按鈕以向服務(wù)器提交表單。

Symfony附帶了許多內(nèi)置類型,它們將被簡(jiǎn)短地介紹(見(jiàn)下面的內(nèi)置表單類型)。

渲染表單 ?

表單創(chuàng)建之后,下一步就是渲染它。這是通過(guò)傳遞一個(gè)特定的表單“view”對(duì)象(注意上例控制器中的  $form->createView() 方法)到你的模板,并通過(guò)一系列的表單helper function(幫助函數(shù))來(lái)實(shí)現(xiàn)的。

TWIG:{# app/Resources/views/default/new.html.twig #}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
PHP:<!-- app/Resources/views/default/new.html.php -->
<?php echo $view['form']->start($form) ?>
<?php echo $view['form']->widget($form) ?>
<?php echo $view['form']->end($form) ?>

1465202253_36066_5344_form-simple.png

本例假設(shè)你以"POST"請(qǐng)求提交表單,并且提交到和“表單顯示(頁(yè)面)”相同的URL。后面你將學(xué)習(xí)如何改變請(qǐng)求方法(request method)和表單提交后的目標(biāo)URL。

就是這樣!只需要三行就可以渲染出完整的form表單:

  • form_start(form)
  • 渲染表單的開(kāi)始標(biāo)簽,包括在使用文件上傳時(shí)的正確enctype屬性。
  • form_widget(form)
  • 渲染出全部字段,包含字段元素本身,字段label以及字段驗(yàn)證的任何錯(cuò)誤信息。
  • form_end(form)
  • 當(dāng)你手動(dòng)生成每個(gè)字段時(shí),它可以渲染表單結(jié)束標(biāo)簽以及表單中所有尚未渲染的字段。這在渲染隱藏字段以及利用自動(dòng)的 CSRF Protection 保護(hù)機(jī)制時(shí)非常有用。

就是這么簡(jiǎn)單,但不太靈活(暫時(shí))。通常情況下,你希望單獨(dú)渲染出表單中的每一個(gè)字段,以便控制表單的樣式。你將在后面 如何去控制表單渲染 文章中掌握這種方法。

在繼續(xù)下去之前,請(qǐng)注意,為什么渲染出來(lái)的 task 輸入框中有一個(gè)來(lái)自 $task 對(duì)象的屬性值(即“Write a blog post”)。這是表單的第一個(gè)任務(wù):從一個(gè)對(duì)象中獲取數(shù)據(jù)并把它轉(zhuǎn)換成一種適當(dāng)?shù)母袷?,以便在HTML表單中被渲染。

表單系統(tǒng)足夠智能,它們通過(guò) getTask()setTask() 方法來(lái)訪問(wèn) Task 類中受保護(hù)的 task 屬性。除非是public屬性,否則 必須 有一個(gè) "getter" 和 "setter" 方法被定義,以便表單組件能從這些屬性中獲取和寫(xiě)入數(shù)據(jù)。對(duì)于布爾型的屬性,你可以使用一個(gè) "isser" 和 "hasser" 方法(如  isPublished()hasReminder() )來(lái)替代getter方法(getPublished()getReminder())。

處理表單提交 ?

默認(rèn)時(shí),表單會(huì)把POST請(qǐng)求,向“渲染它的同一個(gè)控制器”提交回去。

此處,表單的第二個(gè)任務(wù)就是把用戶提交的數(shù)據(jù)傳回到一個(gè)對(duì)象的屬性之中。要做到這一點(diǎn),用戶提交的數(shù)據(jù)必須寫(xiě)入表單對(duì)象才行。向控制器(Controller)中添加以下功能:

// ...use Symfony\Component\HttpFoundation\Request; public function newAction(Request $request){
    // just setup a fresh $task object (remove the dummy data)
    // 直接設(shè)置一個(gè)全新$task對(duì)象(刪除了假數(shù)據(jù))
    $task = new Task();     $form = $this->createFormBuilder($task)
        ->add('task', TextType::class)
        ->add('dueDate', DateType::class)
        ->add('save', SubmitType::class, array('label' => 'Create Task'))
        ->getForm();     $form->handleRequest($request);     if ($form->isSubmitted() && $form->isValid()) {         // $form->getData() holds the submitted values
        // but, the original `$task` variable has also been updated
        //  $form->getData() 持有提交過(guò)來(lái)的值
        // 但是,原始的 `$task` 變量也已被更新了
        $task = $form->getData();         // ... perform some action, such as saving the task to the database
        // for example, if Task is a Doctrine entity, save it!
        // 一些操作,比如把任務(wù)存到數(shù)據(jù)庫(kù)中
        // 例如,如果Tast對(duì)象是一個(gè)Doctrine entity,存下它!
        // $em = $this->getDoctrine()->getManager();
        // $em->persist($task);
        // $em->flush();         return $this->redirectToRoute('task_success');
    }     return $this->render('default/new.html.twig', array(
        'form' => $form->createView(),
    ));}

注意 createView() 方法應(yīng)該在 handleRequest 被調(diào)用 之后 再調(diào)用。否則,針對(duì) *_SUBMIT 表單事件的修改,將不會(huì)應(yīng)用到視圖層(比如驗(yàn)證時(shí)的錯(cuò)誤信息)。


控制器(controller)在處理表單時(shí)遵循的是一個(gè)通用模式(common pattern),它有三個(gè)可能的途徑:

  1. 當(dāng)瀏覽器初始加載一個(gè)頁(yè)面時(shí),表單被創(chuàng)建和渲染。handleRequest() 意識(shí)到表單沒(méi)有被提交進(jìn)而什么都不做。如果表單未被提交,isSubmitted() 返回false;

  2. 當(dāng)用戶提交表單時(shí),handleRequest() 會(huì)識(shí)別這個(gè)動(dòng)作并立即將提交的數(shù)據(jù)寫(xiě)入到 $task 對(duì)象的 task and dueDate 屬性。然后該對(duì)象被驗(yàn)證。如果它是無(wú)效的(驗(yàn)證在下一章),isValid() 會(huì)返回 false,進(jìn)而表單被再次渲染,只是這次有驗(yàn)證錯(cuò)誤;

  3. 當(dāng)用戶以合法數(shù)據(jù)提交表單的時(shí),提交的數(shù)據(jù)會(huì)被再次寫(xiě)入到表單,但這一次 isValid() 返回 true。在把用戶重定向到其他一些頁(yè)面之前(如一個(gè)“謝謝”或“成功”的頁(yè)面),你有機(jī)會(huì)用 $task 對(duì)象來(lái)進(jìn)行某些操作(比如把它持久化到數(shù)據(jù)庫(kù))。

    表單成功提交之后的重定向用戶,是為了防止用戶通過(guò)瀏覽器“刷新”按鈕重復(fù)提交數(shù)據(jù)。

如果你需要精確地控制何時(shí)表單被提交,或哪些數(shù)據(jù)被傳給表單,你可以使用 submit()。更多信息請(qǐng)參考 手動(dòng)調(diào)用Form::submit()

表單驗(yàn)證 ?

在上一節(jié)中,你了解了附帶了有效或無(wú)效數(shù)據(jù)的表單是如何被提交的。在Symfony中,驗(yàn)證環(huán)節(jié)是在底層對(duì)象中進(jìn)行的(例如 Task)。換句話說(shuō),問(wèn)題不在于“表單”是否有效,而是 $task 對(duì)象在“提交的數(shù)據(jù)應(yīng)用到表單”之后是否合法。調(diào)用 $form->isvalid()  是一個(gè)快捷方式,詢問(wèn)底層  $task 對(duì)象是否獲得了合法數(shù)據(jù)。

驗(yàn)證(validation)是通過(guò)把一組規(guī)則(稱之為“constraints/約束”)添加到一個(gè)類中來(lái)完成的。我們給 Task 類添加規(guī)則和約束,使task屬性不能為空, duDate 字段不空且必須是一個(gè)有效的DateTime對(duì)象。

Annotations:// src/AppBundle/Entity/Task.phpnamespace AppBundle\Entity; use Symfony\Component\Validator\Constraints as Assert; class Task{
    /**
     * @Assert\NotBlank()
     */
    public $task;     /**
     * @Assert\NotBlank()
     * @Assert\Type("\DateTime")
     */
    protected $dueDate;}
YAML:# src/AppBundle/Resources/config/validation.ymlAppBundle\Entity\Task:
    properties:
        task:
            - NotBlank: ~
        dueDate:
            - NotBlank: ~
            - Type: \DateTime
XML:<!-- src/AppBundle/Resources/config/validation.xml --><?xml version="1.0" encoding="UTF-8"?><constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping        http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">     <class name="AppBundle\Entity\Task">
        <property name="task">
            <constraint name="NotBlank" />
        </property>
        <property name="dueDate">
            <constraint name="NotBlank" />
            <constraint name="Type">\DateTime</constraint>
        </property>
    </class></constraint-mapping>
PHP:// src/AppBundle/Entity/Task.phpuse Symfony\Component\Validator\Mapping\ClassMetadata;use Symfony\Component\Validator\Constraints\NotBlank;use Symfony\Component\Validator\Constraints\Type; class Task{
    // ...     public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('task', new NotBlank());         $metadata->addPropertyConstraint('dueDate', new NotBlank());
        $metadata->addPropertyConstraint(
            'dueDate',
            new Type('\DateTime')
        );
    }}

就是這樣!如果你現(xiàn)在重新以非法數(shù)據(jù)提交表單,你將會(huì)看到相應(yīng)的錯(cuò)誤被輸出到表單。

驗(yàn)證是Symfony一個(gè)非常強(qiáng)大的功能,它擁有自己的專屬章節(jié)

html5驗(yàn)證

HTML5以來(lái),許多瀏覽器都原生支持了客戶端的驗(yàn)證約束。最常用的驗(yàn)證之激活方式,是在一個(gè)必填字段上渲染一個(gè) required 屬性(譯注:文檔中的“渲染”二字,對(duì)應(yīng)英文rendering,可以理解為“輸出”。在Symfony中,把從程序底層或控制中向視圖層顯示內(nèi)容的過(guò)程,稱為render)。對(duì)于支持HTML5的瀏覽器來(lái)說(shuō),如果用戶嘗試提交一個(gè)空字段到表單時(shí),會(huì)有一條瀏覽器原生信息顯示出來(lái)。

生成出來(lái)的表單充分利用了這個(gè)新功能,通過(guò)添加一些有意義的HTML屬性來(lái)觸發(fā)驗(yàn)證??蛻舳蓑?yàn)證,也可通過(guò)把 novalidate 屬性添加到 form 標(biāo)簽,或是把 formnovalidate 添加到submit標(biāo)簽來(lái)關(guān)閉之。這在你想要測(cè)試服務(wù)器端的驗(yàn)證規(guī)則(validation constraints)卻被瀏覽器端阻止,例如,在提交空白字段時(shí),就非常有用。

PHP:<!-- app/Resources/views/default/new.html.php --><?php echo $view['form']->form($form, array(
    'attr' => array('novalidate' => 'novalidate'),)) ?>


Twig:{# app/Resources/views/default/new.html.twig #}
{{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}

內(nèi)置字段類型 ?

Symfony標(biāo)準(zhǔn)版內(nèi)含巨量字段類型,涵蓋了你所能遇到的全部常規(guī)表單字段和數(shù)據(jù)類型。

文本型字段 ?

選擇型字段 ?

日期和時(shí)間字段 ?

其他類型字段 ?

字段群 ?

隱藏字段 ?

按鈕 ?

表單字段基類 ?

你也可以定義自己的字段類型。參考 如何創(chuàng)建一個(gè)自定義的表單字段類型。

字段類型選項(xiàng) ?

每一種字段類型都有一定數(shù)量的選項(xiàng)用于配置。比如, dueDate 字段當(dāng)前被渲染成3個(gè)選擇框。而 DateType 日期字段可以被配置渲染成一個(gè)單一的文本框(用戶可以輸入字符串作為日期)。

1
->add('dueDate', DateType::class, array('widget' => 'single_text'))

-simple2.png

每一種字段類型都有一系列不同的選項(xiàng)用于傳入此類型。關(guān)于字段類型的細(xì)節(jié)都可以在每種類型的文檔中找到。

required選項(xiàng)

最常用的是 required 選項(xiàng),它可以應(yīng)用于任何字段。默認(rèn)情況下它被設(shè)置為 true 。這就意味著支持HTML5的瀏覽器會(huì)使用客戶端驗(yàn)證來(lái)判斷字段是否為空。如果你不想需要這種行為,要么 關(guān)閉HTML5驗(yàn)證,要么把字段的 required 選項(xiàng)設(shè)置為 false。

->add('dueDate', DateType::class, array(
    'widget' => 'single_text',
    'required' => false))

要注意設(shè)置 requiredtrue 意味著服務(wù)器端驗(yàn)證會(huì)被使用。換句話說(shuō),如果用戶提交一個(gè)空值(blank)到該字段(比如在老舊瀏覽器中,或是使用web service時(shí)),這個(gè)空值當(dāng)被作為有效值予以采納,除非你使用了Symfony的 NotBlank 或者 NotNull 驗(yàn)證約束。

也就是說(shuō), required 選項(xiàng)是很 "nice",但是服務(wù)端驗(yàn)證卻應(yīng)該 始終 使用。

label選項(xiàng)

表單字段可以使用label選項(xiàng)來(lái)設(shè)置表單字段的label,它適用于任何字段:

->add('dueDate', DateType::class, array(
    'widget' => 'single_text',
    'label'  => 'Due Date',))

字段的label也可以在模版渲染表單時(shí)進(jìn)行設(shè)置,見(jiàn)下文。如果你不需要把label關(guān)聯(lián)到你的input(標(biāo)簽),你可以設(shè)置選項(xiàng)值為 false 。

字段類型猜測(cè) ?

現(xiàn)在你已經(jīng)添加了驗(yàn)證元數(shù)據(jù)(譯注:即annotation)到 Task 類,Symfony對(duì)于你的字段已有所了解。如果你允許,Symfony可以“猜到”你的字段類型并幫你設(shè)置好。在下面的例子中,Symfony可以根據(jù)驗(yàn)證規(guī)則猜測(cè)到 task 字段是一個(gè)標(biāo)準(zhǔn)的 TextType 字段, dueDateDateType 字段。

public function newAction(){
    $task = new Task();     $form = $this->createFormBuilder($task)
        ->add('task')
        ->add('dueDate', null, array('widget' => 'single_text'))
        ->add('save', SubmitType::class)
        ->getForm();}

當(dāng)你省略了 add() 方法的第二個(gè)參數(shù)(或者你輸入 null )時(shí),“猜測(cè)”會(huì)被激活。如果你輸入一個(gè)選項(xiàng)數(shù)組作為第三個(gè)參數(shù)(比如上面的 dueDate),這些選項(xiàng)將應(yīng)用于被猜測(cè)的字段。

如果你的表單使用了一個(gè)特定的驗(yàn)證組(validation group),猜測(cè)字段類型時(shí)仍將考慮 所有 驗(yàn)證約束(包括不屬于這個(gè)“正在使用中”的驗(yàn)證組的約束)。

對(duì)字段類型的選項(xiàng)進(jìn)行猜測(cè) ?

除了猜測(cè)字段類型,Symfony還可嘗試猜出字段選項(xiàng)的正確值。

當(dāng)這些選項(xiàng)被設(shè)置時(shí),字段將以特殊的HTML屬性進(jìn)行渲染,以用于HTML5的客戶端驗(yàn)證。然而,它們不會(huì)在服務(wù)端生成相應(yīng)的驗(yàn)證規(guī)則(如 Assert\Length )。盡管你需要手動(dòng)地添加這些服務(wù)器端的規(guī)則,這些字段類型的選項(xiàng)接下來(lái)可以根據(jù)這些規(guī)則被猜出來(lái)。

  • required
  • required 選項(xiàng)可以基于驗(yàn)證規(guī)則 (如,該字段是否為 NotBlankNotNull) 或者是Doctrine的metadata元數(shù)據(jù) (如,該字段是否為 nullable) 而被猜出來(lái)。這非常有用,因?yàn)槟愕目蛻舳蓑?yàn)證將自動(dòng)匹配到你的驗(yàn)證規(guī)則。
  • max_length
  • 如果字段是某些列文本型字段,那么 max_length 選項(xiàng)可以基于驗(yàn)證約束 (字段是否應(yīng)用了 LengthRange) 或者是Doctrine元數(shù)據(jù) (通過(guò)該字段的長(zhǎng)度) 而被猜出來(lái)。

這些字段選項(xiàng) 在你使用Symfony進(jìn)行類型猜測(cè)時(shí)(即,忽略參數(shù),或傳入null 作為 add() 方法的第二個(gè)參數(shù))才會(huì)被猜測(cè)。

如果你希望改變某個(gè)被猜出來(lái)的(選項(xiàng))值,可以在字段類型的選項(xiàng)數(shù)組中傳入此項(xiàng)進(jìn)行覆寫(xiě)。

1
->add('task', null, array('attr' => array('maxlength' => 4)))

創(chuàng)建表單類 ?

正如你看到的,表單可以直接在控制器中被創(chuàng)建和使用。然而,一個(gè)更好的做法,是在一個(gè)單獨(dú)的PHP類中創(chuàng)建表單。它能在你程序中的任何地方復(fù)用。創(chuàng)建一個(gè)持有“構(gòu)建task表單”所需邏輯的新類:

// src/AppBundle/Form/Type/TaskType.phpnamespace AppBundle\Form\Type; use Symfony\Component\Form\AbstractType;use Symfony\Component\Form\FormBuilderInterface;use Symfony\Component\Form\Extension\Core\Type\SubmitType; class TaskType extends AbstractType{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('task')
            ->add('dueDate', null, array('widget' => 'single_text'))
            ->add('save', SubmitType::class)
        ;
    }}

這個(gè)新類包含了創(chuàng)建task表單所需要的方方面面。它可用于在控制器中快速創(chuàng)建表單。

// src/AppBundle/Controller/DefaultController.phpuse AppBundle\Form\Type\TaskType; public function newAction(){
    $task = ...;
    $form = $this->createForm(TaskType::class, $task);     // ...}

把表單邏輯置于它自己的類中,可以讓表單很容易地在你的項(xiàng)目任何地方復(fù)用。這是創(chuàng)建表單最好的方式,但是決定權(quán)在你。

設(shè)置data_class

每個(gè)表單都需要知道“持有底層數(shù)據(jù)的類”的名稱(如 AppBundle\Entity\Task )。通常情況下,這是根據(jù)傳入 createForm 方法的第二個(gè)參數(shù)來(lái)猜測(cè)的(例如 $task )。以后,當(dāng)你開(kāi)始嵌入表單時(shí),這便不再夠用。因此,雖然不是絕對(duì)必須,但通過(guò)添加下面代碼到你的表單類型類中,以顯式地指定 data_class 選項(xiàng)是一個(gè)好辦法。

use Symfony\Component\OptionsResolver\OptionsResolver; public function configureOptions(OptionsResolver $resolver){
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Task',
    ));}

當(dāng)把表單映射成對(duì)象時(shí),所有的字段都將被映射。表單中的任何字段如果在映射對(duì)象上“不存在”,都會(huì)拋出異常。

當(dāng)你需要在表單中使用附加字段(如,一個(gè) “你是否同意這些聲明?”的復(fù)選框)而這個(gè)字段將不被映射到底層對(duì)象時(shí),你需要設(shè)置 mapped 選項(xiàng)為 false

use Symfony\Component\Form\FormBuilderInterface; public function buildForm(FormBuilderInterface $builder, array $options){
    $builder
        ->add('task')
        ->add('dueDate', null, array('mapped' => false))
        ->add('save', SubmitType::class)
    ;}

另外,若表單的任何字段未包含在提交過(guò)來(lái)的數(shù)據(jù)中,那么這些字段將被顯式設(shè)置為 null。

在控制器中我們可以訪問(wèn)字段的data(字段取值):

1
$form->get('dueDate')->getData();

此外,未被映射的字段之?dāng)?shù)據(jù),也可直接修改:

1
$form->get('dueDate')->setData(new \DateTime());

最后的思考 ?

構(gòu)建表單時(shí),牢記首要目標(biāo)是把一個(gè)對(duì)象(task)的數(shù)據(jù)轉(zhuǎn)換成一個(gè)HTML表單,以便用戶能夠修改(表單)取值。第二個(gè)目標(biāo)就是要取到用戶提交的數(shù)據(jù),并重新作用于該對(duì)象。

還有很多內(nèi)容需要掌握,F(xiàn)orm系統(tǒng)有大量 威力強(qiáng)大 的高級(jí)技巧。