2016年10月5日 星期三

[Laravel 5 教程学习笔记] 十、Forms 表单

前面介绍了如何显示列表与单个文章,这一节介绍添加发布文章。首先需要有一个表单,然后需要获取表单的数据并插入到数据库,最后跳转到列表页。

一、注册路由

  1. Route::get('articles/create', 'ArticlesController@create');

二、修改控制器

添加 create() 方法:
  1. public function create(){
  2. return view('articles.create');
  3. }

三、创建视图

可以通过普通的 form 标签创建表单,但是这里使用 illuminate/html 库来创建。当然还可以使用 laravelcollective/html 库,其操作可以参考 文档

3.1 引入HTML库依赖

命令行运行:
  1. composer require illuminate/html
安装过程需要一段时间,可以使用《Windows下安装Laravel 5》中介绍的修改 Composer 源的方法加快安装速度。
安装完成之后,修改 config/app.php 文件,把库注册到 Laravel 中。在 providers 字段中添加HtmlServiceProvider :
  1. // 添加到 'Illuminate\View\ViewServiceProvider', 后面
  2. 'Illuminate\Html\HtmlServiceProvider',
接着通过 aliases 字段为刚才注册的 Provider 设置别名:
  1. // 添加到 'View' => 'Illuminate\Support\Facades\View', 之后
  2. 'Form' => 'Illuminate\Html\FormFacade',
  3. 'Html' => 'Illuminate\Html\HtmlFacade',
设置别名后,在控制器中调用的时候就不需要输入 Facade 的完整名称,只需要使用别名即可。

3.2 创建视图文件

接着创建视图文件 resources/views/articles/create.blade.php :
  1. @extends('main')
  2.  
  3. @section('content')
  4. Wirte a New Article</h1>
  5.  
  6. <hr/>
  7.  
  8. {!! Form::open() !!}
  9.  
  10. {!! Form::close() !!}
  11. @stop

3.3 调整路由顺序

然后在浏览器访问 http://laravel.dev/articles/create ,发现提示错误:
  1. ModelNotFoundException in Builder.php line 125:
  2. No query results for model [App\Article].
我们已经创建了 create() 方法,而且也创建了视图文件,为什么会出现这个错误呢?查看route.php 文件:
  1. Route::get('articles', 'ArticlesController@index');
  2. Route::get('articles/{id}', 'ArticlesController@show');
  3. Route::get('articles/create', 'ArticlesController@create');
注意 {id} 是一个通配符,它会匹配 /articles/ 后面所有的内容,所以当我们访问/articles/create 的时候,它会匹配到 create ,然后进入 ArticlesController@show,而非 ArticlesController@create 。解决方法很简单,就是调整下这两个路由的顺序:
  1. Route::get('articles', 'ArticlesController@index');
  2. Route::get('articles/create', 'ArticlesController@create');
  3. Route::get('articles/{id}', 'ArticlesController@show');
注:以后设置路由都要注意此问题,顺序从特殊到普通。
再次访问 http://laravel.dev/articles/create,一切正常了。查看页面源文件:
laravel-form
可以看到,模版中那一段代码已经为我们生成了一个 form 表单,mothod 默认为POSTaction 为当前RUL,并且生成了一个隐藏域 _token ,它可以让表单提交更加安全。

3.4 修改视图

下面修改视图文件:
  1. @extends('main')
  2.  
  3. @section('content')
  4. Wirte a New Article</h1>
  5.  
  6. <hr/>
  7.  
  8. {!! Form::open() !!}
  9. <div class="form-group">
  10. {!! Form::label('title', 'Title:') !!}
  11. {!! Form::text('title', null, ['class' => 'form-control']) !!}
  12. </div>
  13.  
  14. <div class="form-group">
  15. {!! Form::label('body', 'Body:') !!}
  16. {!! Form::textarea('body', null, ['class' => 'form-control']) !!}
  17. </div>
  18.  
  19. <div class="form-group">
  20. {!! Form::submit('Add Article', ['class' => 'btn btn-primary form-control']) !!}
  21. </div>
  22. {!! Form::close() !!}
  23. @stop
上面的表单会默认提交到 /articles/create ,而我们希望把它提交到 /articles ,所以需要定义一个新的路由:
  1. Route::post('articles', 'ArticlesController@store');
这个路由中,我们需要接受 POST 提交的数据,存入数据库,然后重定向页面。
接着修改视图文件:
  1. {!! Form::open(['url' => '/articles']) !!}
上面的 url() 也可以用 action() 方法,也可以直接写 /articles 。

3.5 修改控制器文件

  1. //文件顶部删除改行 use Illuminate\Http\Request;
  2. //添加下面的 Facade
  3. use Request;
  4.  
  5. //Controller中添加 store() 方法
  6. public function store(){
  7. $input = Request::all();
  8.  
  9. return $input;
  10. }
在表单中添加数据,然后提交,可以到底页面以JSON形式返回了刚才输入的数据。可以使用Request::get('title'); 和 Request::get('body'); 来获取单个字段的值。
现在可以使用 Eloquent ORM 中介绍的方法来向数据库中添加数据了。这里我们不担心 SQL注入 等问题,因为Eloquent模型已经帮我们处理好了。并且我们前面已经在 Article 模型中定义了$fillable 字段,模型只接受该字段中定义了的字段属性,其他的字段都会被过滤掉。
  1. public function store(){
  2. $input = Request::all();
  3.  
  4. Article::create($input);
  5.  
  6. return redirect('articles');
  7. }
这时再重新提交表单,可以看得成功添加了一条记录。但是我们前面定义的 published_at 还需要处理一下:
  1. // 使用Carbon
  2. use Carbon\Carbon;
  3.  
  4. //修改store()方法
  5. public function store(){
  6. $input = Request::all();
  7. $input['published_at'] = Carbon::now();
  8.  
  9. Article::create($input);
  10.  
  11. return redirect('articles');
  12. }
再次添加数据提交表单,可以看到生成的数据已经完整了。但是还有个小的问题,就是列表页显示的文章顺序是从旧到新的,而我们想要的的从新到旧,所以需要修改 index() 方法:
  1. public function index(){
  2. //方法一
  3. $articles = Article::latest('published_at')->get();
  4. //方法二
  5. //$articles = Article::orderBy('published_at', 'desc')->get();
  6.  
  7. return view('articles.index', compact('articles'));
  8. //或者也可以使用这种方式
  9. //return view('articles.index')->with('articles', $articles);
  10. }
再次刷新列表页,发现顺序已经变成了从新到旧。
这时,我们再到文章添加页,不填写任何内容,直接提交表单,发现数据库也会多出一条数据,这是因为我们对输入的数据没有做任何的验证,这显然是不行的,下一节将介绍表单验证。


from : http://9iphp.com/web/laravel/laravel-froms.html

沒有留言:

wibiya widget