handleRequest() 在同一请求中调用两次,$Action 不同
handleRequest() called twice in same request, $Action is different
我有一条自定义路线:
/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/ 服务器响应:
Action '1' isn't available on class UploadImportedCourseForm.
深入研究 RequestHandler
中的 handleRequest
我发现它被调用了两次,每次都到达第 180 行,它查看对象 latestParam()
。第一次叫Action是Edit,意料之中,第二次叫1,其实就是ID。
同一个请求中的操作有何变化?我该如何着手解决我的问题?我认为我可以解决此问题的唯一方法是改为使用 ID 隐藏字段。
一般来说,创建表单的方法不应该过于复杂。他们只需要 return 一个表格。关于动态 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-aware。如果您要执行大量此类操作,这将使您的扩展更加清晰。
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-aware,因此永远不会混淆事物的来源。您已经从中提取了 post vars 和 URLs 的抽象。
我有一条自定义路线:
/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/ 服务器响应:
Action '1' isn't available on class UploadImportedCourseForm.
深入研究 RequestHandler
中的 handleRequest
我发现它被调用了两次,每次都到达第 180 行,它查看对象 latestParam()
。第一次叫Action是Edit,意料之中,第二次叫1,其实就是ID。
同一个请求中的操作有何变化?我该如何着手解决我的问题?我认为我可以解决此问题的唯一方法是改为使用 ID 隐藏字段。
一般来说,创建表单的方法不应该过于复杂。他们只需要 return 一个表格。关于动态 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-aware。如果您要执行大量此类操作,这将使您的扩展更加清晰。
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-aware,因此永远不会混淆事物的来源。您已经从中提取了 post vars 和 URLs 的抽象。