Menu

58.重构

本节说明

  • 对应视频教程第 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>
    .
    .

现在我们尝试提交空回复:
file
但是现在我们还是有一些小问题要修复:

  1. 点击Update按钮,页面会刷新;
  2. 更新回复时,如果点击取消,页面会显示编辑后的内容。

让我们来进行修复:

<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>

现在来进行测试:
file
然后我们再来看 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));
            });
    }
}

如果你担心重构会破坏已有的功能,你只需要运行全部测试即可:
file

本文章首发在 Laravel China 社区
上一篇 下一篇
讨论数量: 0
发起讨论


暂无话题~