PHP使用Slim处理来自Actions的AJAX
我有一个关于php和带有超薄框架的AJAX的问题
我创建了一些路由将我路由到一个控制器,现在我想用AJAX提交一个简单的表单。这可以很好地工作,但问题是,如果我要在没有AJAX的情况下提交表单,我会向服务器发送POST请求,这将调用控制器中的createAction而不是form renderAction方法(请参见代码)。 但我需要调用formRender,因为当表单无效时,我必须再次向用户显示具有值的表单。
注意:我尚未实现任何验证代码。
这里是我提交表单的JS代码:
$('#reservation').on('submit', function (ev) {
ev.preventDefault();
var data = $(this).serialize();
var keyVal = data.split("&");
var values = [];
keyVal.forEach(function (element) {
values[element.split("=")[0]] = element.split("=")[1];
});
$.post("/admin/reservation/create", data).done(function (data) {
console.log(data);
}).error(function (err) {
});
});
这里是我的控制器的代码:
public function formRender(Request $request, Response $response)
{
$formData = $request->getParams();
return $this->view->render($response, '/reservations/form.twig', [
'formData' => $formData]);
}
public function createAction(Request $request, Response $response)
{
$formData = $request->getParams();
$response = $response->withJson($formData);
return $response;
}
我的路线:
$app->get('/reservation/create', 'ReservationController:formRender');
$app->post('/reservation/create', 'ReservationController:createAction');
这里是视图代码(使用twig):
<form class="col s6" id="reservation" method="post">
<div class="row">
<div class="input-field col s6">
<input placeholder="Titel" id="title" name="title" type="text" class="validate"
value="{{ formData.title }}">
<label for="title">Titel</label>
</div>
<div class="input-field col s12 m6">
<select class="icons" multiple>
<option value="" disabled selected>Choose Rooms</option>
<option value="" data-icon="images/sample-1.jpg" class="circle">example 1</option>
<option value="" data-icon="images/office.jpg" class="circle">example 2</option>
<option value="" data-icon="images/yuna.jpg" class="circle">example 1</option>
</select>
<label>Rooms</label>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<input value="{{ formData.startDate }}" id="startDate" name="startDate" type="date" class="validate">
</div>
<div class="input-field col s6">
<input value="{{ formData.endDate }}" id="endDate" name="endDate" type="date" class="validate">
</div>
</div>
<button type="submit" class="waves-effect waves-light btn">button</button>
</form>
我该如何解决这个问题...所以我希望能够按AJAX发送数据,并且我希望能够在没有js的情况下提交我的表单。我正在寻找一个干净的解决方案..不是用隐藏的领域或其他东西快速而肮脏的修复。 针对此类情况的最佳实践是什么?
解决方案
我建议您命名您的路由来解决这个问题:
$app->get('/reservation/create', 'ReservationController:formRender')->setName('reservationFormRenderer');
$app->post('/reservation/create', 'ReservationController:createAction')->setName('reservationFormAjaxProcessor');
由于您使用的是Twig作为模板引擎,请使用path_for
方法将角色注入到表单:
<form class="col s6" id="reservation" method="post" action="{{ path_for('reservationFormRenderer') }}" data-ajax-processor="{{ path_for('reservationFormAjaxProcessor') }}">
剩下的工作就是在您的JS代码中选择动态路由:
$('#reservation').on('submit', function (ev) {
ev.preventDefault();
var data = $(this).serialize();
var keyVal = data.split("&");
var values = [];
keyVal.forEach(function (element) {
values[element.split("=")[0]] = element.split("=")[1];
});
// here we pass the value of data-ajax-processor attribute of the form
$.post(($this).data('ajax-processor'), data).done(function (data) {
console.log(data);
}).error(function (err) {
});
});
现在,如果表单不是动态提交的(即ajax-way),则处理程序的URL将位于表单的action属性中。
您实际上可以在不命名路由的情况下完成此操作,但这种方式将保持代码的可维护性,因为您只需在一个地方更改实际的URL--即在路由声明中。
相关文章