我有自定义路线:
/create//$Action/$ID
行动:
public function Edit(SS_HTTPRequest $request) {
$id = $this->getRequest()->params()['ID'];
if($this->request->isPost()) return UploadForm::create($this, 'Edit/' . $id, 'SubmitImportedModule');;
return $this->renderWith(array("Edit", "Page"));
}
自定义表单:
class UploadForm extends Form {
public function __construct($controller, $name, $action) {
$fields = FieldList::create(
TextField::create('Title', 'Title'),
$course = UploadField::create('Upload', 'Upload')
);
$actions = FieldList::create(
FormAction::create($action, 'Add Resource')
);
$validator = RequiredFields::create('Name');
parent::__construct($controller, $name, $fields, $actions, $validator);
}
}
如果路径为/ create / Edit /,则上传字段工作正常。但是,如果路径为/ create / Edit / 1 /,则服务器响应:
行动' 1'在UploadImportedCourseForm类上没有。
深入研究handleRequest
中的RequestHandler
我发现这被调用两次,每次都到达第180行,在那里查看对象latestParam()
。第一次它被称为动作是编辑,但是第二次它是第一次它是1,这实际上是ID。
如何在同一请求中更改操作以及如何解决问题?我认为我可以解决这个问题的唯一方法是使用带有ID的隐藏字段。
答案 0 :(得分:1)
通常,创建表单的方法不应过于复杂。他们只需要退回表格。关于动态ID,您可以通过几种不同的方式执行此操作 - 您可以通过隐藏字段传入ID,并创建像getIDFromRequest()
这样的方法来检查URL和请求正文。
private static $allowed_actions = ['EditForm'];
public function EditForm() {
return UploadForm::create($this, __FUNCTION__, 'yourAction');
}
class UploadForm extends Form {
protected function getIDFromRequest(SS_HTTPRequest $r)
{
return $r->param('ID') ?: $r->postVar('ID');
}
public function __construct($controller, $name, $action) {
$fields = FieldList::create(
TextField::create('Title', 'Title'),
HiddenField::create('ID','', $this->getIDFromRequest($controller->getRequest())),
$course = UploadField::create('Upload', 'Upload')
);
$actions = FieldList::create(
FormAction::create($action, 'Add Resource')
);
$validator = RequiredFields::create('Name');
parent::__construct($controller, $name, $fields, $actions, $validator);
}
}
或者,基于我可以推断出您尝试做的事情,我认为子控制器在这里会更有意义。创建一个可识别ID的单独请求处理程序。如果您正在进行大量此类操作,这将使您可以更加干净地扩展。
private static $url_handlers [
'yourpath/$ID' => 'handleEditForm'
];
private static $allowed_actions = ['handleEditForm'];
public function handleEditForm(SS_HTTPRequest $r)
{
$obj = SomeObject::get()->byID($r->param('ID')) {
if(!$obj) $this->httpError(404);
}
$handler = new MyController_EditRequest($this, $obj);
return $handler->handleRequest($r, DataModel::inst());
}
class MyController_EditRequest extends RequestHandler
{
protected $parent;
protected $obj;
private static $allowed_actions = ['edit', 'EditForm'];
public function __construct(MyController $controller, SomeDataObject, $obj)
{
$this->parent = $controller;
$this->obj = $obj;
parent::__construct();
}
public function edit(SS_HTTPRequest $r)
{
return $this->renderWith(['SomeTemplate_edit','Page']);
}
public function Link()
{
return $this->parent->Link('yourpath/'.$this->obj->ID);
}
public function EditForm()
{
return UploadForm::create($this, __FUNCTION__, 'yourAction', $obj->ID)
}
}
class UploadForm extends Form {
public function __construct($controller, $name, $action, $id) {
$fields = FieldList::create(
TextField::create('Title', 'Title'),
HiddenField::create('ID','', $id),
$course = UploadField::create('Upload', 'Upload')
);
$actions = FieldList::create(
FormAction::create($action, 'Add Resource')
);
$validator = RequiredFields::create('Name');
parent::__construct($controller, $name, $fields, $actions, $validator);
}
}
您的子控制器是DataObject感知的,因此对于事物的来源绝不会产生任何混淆。您已经从中抽取了后变量和URL。