Laravel - 从视图中调用 Redirect::to()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18846035/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel - Calling Redirect::to() from within view
提问by ArranJacques
I'm currently working on a cms which is built on the Laravel 4 framework. I'm trying to build a plugin system, similar to Pyro CMS, where module views can be included in a page view using the Blade template system.
我目前正在开发一个基于 Laravel 4 框架的 cms。我正在尝试构建一个插件系统,类似于 Pyro CMS,其中模块视图可以包含在使用 Blade 模板系统的页面视图中。
I'm building a contact form plugin that if submitted successfully will redirect the user to a given url, or simply redirect back to the existing page.
我正在构建一个联系表单插件,如果提交成功,会将用户重定向到给定的 url,或者只是重定向回现有页面。
The code for my contact form class is:
我的联系表单类的代码是:
class Contact {
public static function form($params)
{
//get params and execute relevant logic here
$redirect = isset($params['redirect']) ? $params['redirect'] : Request::url();
$data = Input::all();
if($data)
{
// Run validation and send message here
return Redirect::to($redirect)
}
return View::make('contact_form_view');
}
}
There is a page controller that will display the appropriate page view depending on the route used and the idea is that a user can drop a contact form into any page template and easily customise it by calling the form function from within the template view as shown below
有一个页面控制器将根据所使用的路由显示适当的页面视图,其想法是用户可以将联系表单放入任何页面模板中,并通过从模板视图中调用表单函数轻松自定义它,如下所示
<html>
<head>
</head>
<body>
{{ Contact::form(array(
'to' => '[email protected]',
'view' => 'contact_form_1',
)) }}
</body>
</html>
This all works fine apart from the redirect. When the form is successfully submitted and the message sent the page refreshes and displays the following message in place of the contact form
除了重定向之外,这一切都很好。当表单成功提交并发送消息时,页面刷新并显示以下消息代替联系表单
HTTP/1.0 302 Found Cache-Control: no-cache Date: Tue, 17 Sep 2013 09:14:16 GMT Location: http://localhost:8888/my_initial_route Redirecting to http://localhost:8888/my_new_route.
About 2 seconds later the redirect then takes place and the browser is redirected to whatever route the user provides in the $params array, or to the current page if no redirect is provided, as in the example above.
大约 2 秒后,重定向发生,浏览器被重定向到用户在 $params 数组中提供的任何路由,或者如果没有提供重定向,则重定向到当前页面,如上例所示。
Any suggestions as to why it is doing this, as well as any solutions, would be great.
关于为什么这样做的任何建议以及任何解决方案都会很棒。
Thanks!
谢谢!
EDIT:
编辑:
Here is a really brief overview of why I have taken the above approach, which might help with understanding the problem:
以下是我为何采用上述方法的简要概述,这可能有助于理解问题:
A requirement of the project is that the developers that will eventually use the cms can create a indefinite amount of pages via the cms control panel by clicking an "Add page" button. The idea is that we aren't writing new page controllers for every new page we want to create. With that I mind I have the following route:
该项目的一个要求是,最终将使用 cms 的开发人员可以通过单击“添加页面”按钮通过 cms 控制面板创建无限数量的页面。这个想法是我们不会为我们想要创建的每个新页面编写新的页面控制器。考虑到这一点,我有以下路线:
Route::any('{page_slug}/page', array('as' => 'frontend.page', 'uses' => 'FrontendPagesController@display_page'))->where('page_slug', '[-A-Za-z0-9_-]+');
The display_page
function slimmed greatly is:
display_page
大大瘦身的功能是:
public function display_page($slug)
{
$page = PagesModel::getPageBySlug($slug);
return View::make($page['view_name']);
}
With this users can create a page with the click of a button, give it a name and a slug, and the app can then display that page and the corresponding view -- defined when creating the page -- without having to add any new routes, controllers etc.
有了这个,用户可以通过单击按钮创建一个页面,给它一个名称和一个 slug,然后应用程序可以显示该页面和相应的视图——在创建页面时定义——而无需添加任何新路由、控制器等
The problem arrises in a situation where a user wants to include a contact form with a page. How do we know if they will add a form or not, what fields they will use and what validation it will require? I need a way of being able to add a completely custom contact form into any page without the developer having to touch touch the cms code. My solution to this was the approach given above: the developer drops the tag into the view and passes the function some params, which customise the forms functionality.
该问题出现在用户想要在页面中包含联系表单的情况下。我们如何知道他们是否会添加表单,他们将使用哪些字段以及需要哪些验证?我需要一种能够将完全自定义的联系表单添加到任何页面的方法,而无需开发人员触摸 cms 代码。我对此的解决方案是上面给出的方法:开发人员将标签放入视图中并向函数传递一些参数,这些参数自定义表单功能。
The Contact::form()
function is kind of like a controller for the form. It gets and returns the view that contains the from html, processes the submission and returns success/errors messages depending on the outcome.
该Contact::form()
函数有点像表单的控制器。它获取并返回包含来自 html 的视图,处理提交并根据结果返回成功/错误消息。
Now I don't necessarily need to use the approach above but I need a way of separating the contact form controller from the page controller and for developers to be able to add a form to any page without touching the cms backend code.
现在我不一定需要使用上面的方法,但我需要一种将联系表单控制器与页面控制器分开的方法,并使开发人员能够在不接触 cms 后端代码的情况下将表单添加到任何页面。
Any ideas on this would be great.
对此的任何想法都会很棒。
回答by The Alpha
You should call the redirect
from a controller instead of doing it from the view. This is happening because, you are already in the view and it's visible, so if you somehow could make it (the body) hidden then it won't be visible before redirect happens.
您应该redirect
从控制器调用而不是从视图中调用。发生这种情况是因为,您已经在视图中并且它是可见的,所以如果您可以以某种方式隐藏它(主体),那么它在重定向发生之前将不可见。
But, you are doing it wrong and anti-pattern
, IMO. Use the controller to make decision, view should be used only for presentation. This is the very basic rule in an MVC
framework.
但是,你做错了anti-pattern
,IMO。使用控制器来做决定,视图应该只用于展示。这是MVC
框架中非常基本的规则。
回答by J.T. Grimes
When you call a function in the view, it should return HTML which is then displayed. For instance, when you call {{ Url::to('foo') }}
it generates http://yoursite.tld/foo.
当你在视图中调用一个函数时,它应该返回 HTML,然后显示。例如,当您调用{{ Url::to('foo') }}
它时会生成http://yoursite.tld/foo。
When you call {{Contact::form(...)}}
, it should output HTML. When you return View::make(...)
, you're returning HTML. When you return Redirect::to(...)
, you're returning a Laravel object which the Laravel router parses into a redirect header.
当您调用 时{{Contact::form(...)}}
,它应该输出 HTML。当您 return 时View::make(...)
,您将返回 HTML。当您 return 时Redirect::to(...)
,您将返回一个 Laravel 对象,Laravel 路由器将其解析为重定向标头。
Redirects pretty much have to be called either by Route objects or by controllers. If you have your form submission handled by a controller, put your redirect there.
重定向几乎必须由 Route 对象或控制器调用。如果您的表单提交由控制器处理,请将您的重定向放在那里。
回答by Antonio Carlos Ribeiro
Just got this very same problem, downgraded to "4.0.*" and it's fixed.
刚刚遇到了同样的问题,降级为“4.0.*”并已修复。
Looks like this is a 4.1.x problem.
看起来这是一个 4.1.x 问题。
Steps to downgrade
降级步骤
Change composer.json to:
将 composer.json 更改为:
"require": {
...
"laravel/framework": "4.0.x",
...
}
edit app.php - 'Controller' alias
编辑 app.php - 'Controller' 别名
'Controller' => 'Illuminate\Routing\Controller',
Should become
应该成为
'Controller' => 'Illuminate\Routing\Controllers\Controller',
And I had to remove those service providers
我不得不删除那些服务提供商
'Illuminate\Remote\RemoteServiceProvider',
'Illuminate\Exception\LiveServiceProvider',
EDIT:
编辑:
I've opened an issue about this on Github and earlier Taylor fixed it. Do a composer update and you should be fine.
我已经在 Github 上打开了一个关于这个的问题,早些时候 Taylor 修复了它。做一个作曲家更新,你应该没问题。
回答by Kiko Seijo
The simple way:
简单的方法:
header('Location: '.route('clients.create'));