58.重构
- 本系列文章为
laracasts.com
的系列视频教程——Let's Build A Forum with Laravel and TDD 的学习笔记。若喜欢该系列视频,可去该网站订阅后下载该系列视频, 支持正版 ;- 视频源码地址:github.com/laracasts/Lets-Build-a-...;
- 本项目为一个 forum(论坛)项目,与本站的第二本实战教程 《Laravel 教程 - Web 开发实战进阶》 类似,可互相参照。
本节说明
- 对应视频教程第 58 小节:Don't Forget to Scan Your Files
本节内容
现在我们所有的测试都已经通过,但是,让我们停下脚步,浏览我们的代码,看我们能否做些有益处的重构。首先我们来看一下更新回复的动作:
forum\app\Http\Controllers\RepliesController.php
public function update(Reply $reply)
{
$this->authorize('update',$reply);
try{
$this->validate(request(),['body' => 'required|spamfree']);
$reply->update(request(['body']));
}catch (\Exception $e){
return response(
'Sorry,your reply could not be saved at this time.',422
);
}
}
上面那段代码我们可以修改如下:
public function update(Reply $reply)
{
$this->authorize('update',$reply);
$this->validate(request(),['body' => 'required|spamfree']);
$reply->update(request(['body']));
}
同时,前端页面需要相应修改:
forum\resources\assets\js\components\Reply.vue
.
.
<div class="panel-body">
<div v-if="editing">
<form @submit="update">
<div class="form-group">
<textarea class="form-control" v-model="body" required></textarea>
</div>
<button class="btn btn-xs btn-primary">Update</button>
<button class="btn btn-xs btn-link" @click="editing = false" type="button">Cancel</button>
</form>
</div>
<div v-else v-text="body"> </div>
</div>
.
.
现在我们尝试提交空回复:
但是现在我们还是有一些小问题要修复:
- 点击
Update
按钮,页面会刷新; - 更新回复时,如果点击取消,页面会显示编辑后的内容。
让我们来进行修复:
<template>
<div :id="'reply'+id" class="panel panel-default">
.
.
<div class="panel-body">
<div v-if="editing">
<form @submit.prevent="update">
<div class="form-group">
<textarea class="form-control" v-model="body" required></textarea>
</div>
<button class="btn btn-xs btn-primary" >Update</button>
<button class="btn btn-xs btn-link" @click="cancelReply" type="button">Cancel</button>
</form>
</div>
<div v-else v-text="body"> </div>
</div>
<div class="panel-footer level" v-if="canUpdate">
<button class="btn btn-xs mr-1" @click="editReply">Edit</button>
<button class="btn btn-xs btn-danger mr-1" @click="destroy">Delete</button>
</div>
</div>
</template>
<script>
.
.
methods:{
.
.
destroy() {
axios.delete('/replies/' + this.data.id);
this.$emit('deleted',this.data.id);
},
editReply(){
this.old_body_data = this.body;
this.editing = true;
},
cancelReply(){
this.body = this.old_body_data;
this.old_body_data = '';
this.editing = false;
},
}
}
</script>
现在来进行测试:
然后我们再来看 forum\app\Listeners\NotifyMentionedUsers.php:
<?php
namespace App\Listeners;
use App\Events\ThreadReceivedNewReply;
use App\Notifications\YouWereMentioned;
use App\User;
class NotifyMentionedUsers
{
/**
* Handle the event.
*
* @param ThreadReceivedNewReply $event
* @return void
*/
public function handle(ThreadReceivedNewReply $event)
{
collect($event->reply->mentionedUsers())
->map(function ($name) {
return User::where('name',$name)->first();
})
->filter()
->each(function ($user) use ($event){
$user->notify(new YouWereMentioned($event->reply));
});
}
}
在这里我们能够进行的重构是,一次性取出所有被 @ 的用户名,而不是循环取出。所以我们修改如下:
<?php
namespace App\Listeners;
use App\Events\ThreadReceivedNewReply;
use App\Notifications\YouWereMentioned;
use App\User;
class NotifyMentionedUsers
{
/**
* Handle the event.
*
* @param ThreadReceivedNewReply $event
* @return void
*/
public function handle(ThreadReceivedNewReply $event)
{
User::whereIn('name',$event->reply->mentionedUsers())
->get()
->each(function ($user) use ($event){
$user->notify(new YouWereMentioned($event->reply));
});
}
}
如果你担心重构会破坏已有的功能,你只需要运行全部测试即可: