【问题标题】:Silverstripe returning a populated form via controllerSilverstripe 通过控制器返回填充表单
【发布时间】:2015-09-23 14:21:07
【问题描述】:

我正在尝试找出返回预先填充数据库数据的表单的正确方法。让我告诉你我现在是怎么做的:

团队页面:

<?php
class TeamsPage extends Page {
  private static $has_many = array (
    'Teams' => 'Team',
  );
  public function getCMSFields() {
    $fields = parent::getCMSFields();
    $fields->addFieldToTab('Root.Teams', GridField::create(
        'Teams',
        'Teams on this page',
        $this->Teams(),
        GridFieldConfig_RecordEditor::create()
    ));
    return $fields;
  }
}
class TeamsPage_Controller extends Page_Controller {
  private static $allowed_actions = array (
    'show', 'edit', 'EditTeamForm'
  );

  public function EditTeamForm($teamId){
    $fields = new FieldList(
        new TextField('TeamName'),
        new TextareaField('TeamDescription')
    );
    $actions = new FieldList(
        new FormAction('EditTeam', 'Save Changes')
    );
    $requiredFields = new RequiredFields(array('TeamName','TeamDescription'));
    $form = new Form($this, 'EditTeamForm', $fields, $actions, $requiredFields);
    $form->setFormMethod('POST', true);

    $data = Session::get("FormData.{$form->getName()}.data");
    $team = Team::get()->byID($teamId);
    return $data ? $form->loadDataFrom($data) : $form->loadDataFrom($team);
  }

  public function show(SS_HTTPRequest $request) {
    $team = Team::get()->byID($request->param('ID'));

    if(!$team) {
        return $this->httpError(404,'That team could not be found');
    }

    return array (
        'Team' => $team
    );
  }

  public function edit(SS_HTTPRequest $request){
    $team = Team::get()->byID($request->param('ID'));

    if(!$team) {
        return $this->httpError(404,'That team could not be found');
    }

    return array (
        'Team' => $team
    );
  }
}

团队:

<?php
class Team extends DataObject {
  private static $db = array(
    'TeamCaptain' => 'Int',
    'TeamName' => 'Varchar',
    'TeamDescription' => 'Text'
  );
  private static $has_one = array (
    'Photo' => 'Image',
    'TeamsPage' => 'TeamsPage'
  );
  private static $summary_fields = array (
    'GridThumbnail' => '',
    'TeamCaptain' => 'Team Captain',
    'TeamName' => 'TeamName',
    'TeamDescription' => 'Team Description',
  );
  public function getGridThumbnail() {
    if($this->Photo()->exists()) {
        return $this->Photo()->SetWidth(100);
    }
    return '(no image)';
  }
  public function getCMSFields() {
    $fields = FieldList::create(
        TextField::create('TeamCaptain'),
        TextField::create('TeamName'),
        TextareaField::create('TeamDescription'),
        $uploader = UploadField::create('Photo')
    );
    $uploader->setFolderName('teams-photos');
    $uploader->getValidator()->setAllowedExtensions(array(
        'png','gif','jpeg','jpg'
    ));
    return $fields;
  }

  public function Link() {
    return $this->TeamsPage()->Link('show/'.$this->ID);
  }
}

TeamsPage_edit.ss

<% if GetMember() %>
  Welcome $getMember.FirstName<br />
  $EditTeamForm($Team.ID)
  <a href="home">Back to Home</a>
<% else %>
  $GoToLogin()
<% end_if %>

正如您在我的控制器中看到的,我返回了一个我不完全理解它是如何工作的 $Team。在我的模板中,我使用 $Team.ID 并试图确定该值是否来自我返回的团队数组或其他方式。我试图理解的另一件事是为什么我不在这里返回表单,为什么我必须有一个单独的函数来创建该表单并且必须在模板中调用它。我在这里看到的最后一个问题是我要查询数据库两次以获取相同的信息。

我最后要问的是,如果有人能告诉我什么是实现我正在做的事情的正确方法。我确信它已经做过很多次了,但是我在互联网上的任何地方都找不到一个关于如何使用编辑表单的例子。我已经找到了如何使用显示操作并返回一堆结果,但没有与表单结合使用。

【问题讨论】:

    标签: forms controller silverstripe


    【解决方案1】:

    我建议简单地执行以下操作(这些是对代码的补充,不是完整的类):

    class TeamPage_Controller extends Page_Controller {
        protected $currentTeam;
    
        protected function getCurrentTeam() {
            if (!isset($this->currentTeam)) {
                $teamID = $this->getRequest()->param('ID') ?: $this->getRequest()->postVar('ID');
                $this->currentTeam = $teamID ? Team::get()->byID($teamID) : null;
            }
            return $this->currentTeam;
        }
    
        public function EditTeamForm() {
             $team = $this->getCurrentTeam();             
             // You'll want to add a HiddenField with the ID if $team is not null
             // everything else is the same
        }
    
        // NOTE: I would suggest you call this something else
        // SS convention would be "doSaveTeam" - it should be whatever your FormAction is called though
        public function EditTeam($data, $form) {
            $team = $this->getCurrentTeam();
            // Save and redirect
        }
    
        public function edit(SS_HTTPRequest $request){
            $team = $this->getCurrentTeam();
            // Blah blah blah
        }
    }
    

    【讨论】:

    • 感谢您发布此信息。我有几个问题。编辑函数返回一个团队。为了在模板中使用它,它必须返回 Team,对吗?另一个问题是,为什么我不能返回预填充的表单而不是团队?不必从模板中调用它,但默认情况下页面会通过函数编辑加载到表单中。
    • 首先,edit 函数返回一个用于填充模板的数组。如果您愿意,它可以将表单对象作为数组的一部分返回。但其次,您需要 EditTeamForm() 可以自行调用,因为在提交表单时控制器不会再次通过 edit() 。它将直接从 EditTeamForm 构建表单,然后调用提交处理程序(我建议您将其重命名为 doSaveTeam 的 EditTeam)。这就是为什么最好不要将任何东西传递给该方法。
    • 这些都是很好的解释,谢谢!我再次断开连接,正如您所说,编辑函数返回一个数组,在这种情况下,它返回一个包含 $team 的数组。在我的模板上,我有 $Team.ID,silverstripe 究竟是如何知道我返回的 $team 实际上是我正在使用的 $Team。我基本上是想了解它是如何从编辑中的 $team 到模板中的 $Team 的。我为这么多问题道歉,但我试图了解整个情况,因为这对我了解我正在实施的内容很重要。尤其是在稍后进行调试时。
    • 没问题。它在模板中称为 $Team,因为您返回的数组中的键是“Team”。如果您返回了 array('MyTeam' => $team),您将使用模板中的 $MyTeam 访问它。您实际上也可以在模板中使用 $CurrentTeam,因为您在控制器上有一个 getCurrentTeam 方法(但您必须先将其公开)。
    • 如果您没有任何数据要传递给模板,您可以只返回一个空数组。如果您返回一个字符串,它会将其解释为预渲染的 HTML。我不确定返回 null 会做什么。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 2022-11-01
    • 2020-08-12
    • 2014-04-21
    相关资源
    最近更新 更多