لارافيل, VueJs / 2024-05-13

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء العاشر - تعديل البيانات

سلسة عمليات CRUD بإستخدام Laravel + VueJs مع SPA - الجزء العاشر - تعديل البيانات

2024-05-13 وقت القراءه : 5 دقائق

في هذه المقال، سيتم الحديث عن تعديل البيانات في لارافيل مع VueJs حيث نحتاج لإنشاء component جديد للتعديل، router-link لصفحة التعديل، إنشاء route في laravel وإنشاء دالتين في PostController واحده show لعرض البيانات حسب Post المرسلل من Vue ودالة update.


خطوات Front End بإستخدام VueJs

إنشاء صفحة التعديل

في المسار resources/js/components/Posts/ ننشئ ملف ليكن بإسم edit.vue

نسخ محتويات صفحة create.vue ولصقها في صفحة edit.vue وذلك لأننا سوف نستخدم نفس الفورم والمتغيرات والدوال لكن مع بعض التعديلات عليها.


إنشاء زر التعديل في صفحة index

هنا بما إننا نتعامل مع spa فسوف نستخدم router-link 

<td>
<router-link :to="{ name:'posts.edit', params:{ id:post.id} }" class="btn btn-success">Edit</router-link>
</td>

توضيح

  • name:posts.edit بما إننا نتعامل مع named route تم إستخدام name وذلك يعني إنه يجب أن يتم إنشاء هذا الـ route بنفس الإسم posts.edit في الملف resources/js/routes/index.js
  • params:id تم إستخدامها لجلب id المقال الذي نريد التعديل علية.

إنشاء route

في الملف resources/js/routes/index.js وهو الملف المخصص للـ route يجب أن نضيف الـ route، مع عمل import لصفحة edit.

import PostIndex from '../components/Posts/index';
import PostCreate from '../components/Posts/create';
import PostEdit from '../components/Posts/edit';


export default {
    mode: 'history',
    routes: [
        {
            path: '/',
            component: PostIndex,
            name: 'posts.index'
        },
        {
            path: '/posts/create',
            component: PostCreate,
            name: 'posts.create'
        },
        {
            path: '/posts/edit/:id',
            component: PostEdit,
            name: 'posts.edit'
        }
    ]
}


جلب البيانات حسب id من backEnd

في PostController نحتاج لإنشاء دالة تستقبل ال Post الذي سيتم التعديل عليه، وإرجاع البيانات الخاصه به

public function show(Post $post)
{
    return new PostResource($post);
}


إنشاء الإتصال مع ال api

في الملف edit.vue نحتاج أنه عندما تفتح الصفحة أن يتم الإتصال مع الـ api لجلب البيانات، لذلك نضع إتصال axios في الدالة mounted

mounted() {
    axios.get('/api/category')
        .then(response => {
            this.categories = response.data.data;
        });
    axios.get('/api/posts/'+this.$route.params.id)
        .then(response => {
            this.fields = response.data.data;
        });
},
  • الإتصال الأول لجلب الأقسام
  • الإتصال الثاني لجلب بيانات المقال، مع الإنتباه إنه تم إرسال id المقال، وذلك من خلال إستخدام this.route.params.id


دالة إرسال البيانات من frontend بإستخدام axios

سوف يتم إستخدام نفس الدالة وهي submiting_form لكن مع بعض التعديلات

methods:{
    submit_form(){
        this.form_submiting=true;
        axios.put('/api/posts/'+this.$route.params.id,this.fields)
            .then(response =>  {
                swal({
                    title:"Post Edited Successfully",
                    icon: "success",
                    button: "Close",
                })
                this.$router.push('/');
                this.form_submiting = false;
            }).catch(error=>{
            if(error.response.status === 422){
                swal({
                    title:"There is an error",
                    icon: "error",
                    button: "Close",
                })
                this.errors = error.response.data.errors;
                this.form_submiting=false;
            }
        });
    }
}

نلاحظ أن نوع الإتصال هو put، وكذلك تم إرسال الـ id من خلال إستخدام this.route.params.id، وكذلك تم إرسال قيم fields من خلال  this.fields.


 إنشاء دالة تعديل البيانات في PostController

public function update(StorePostRequest $request, Post $post)
{
    $post->update($request->validated());
    return new PostResource($post);
}



الكود

كود edit

<template>
    <div>
        <form @submit.prevent="submit_form">
            Post Title:<br/>
            <input type="text" v-model="fields.title" class="form-control"><br/>
            <div class="alert alert-danger" v-if="errors && errors.title">
                {{ errors.title[0]}}
            </div>
            Post Text:<br/>
            <textarea rows="10" v-model="fields.body" class="form-control"></textarea><br/>
            <div class="alert alert-danger" v-if="errors && errors.body">
                {{ errors.title[0]}}
            </div>
            Category:<br/>
            <select class="form-control" v-model="fields.category_id">
                <option value="">==Please Choose Categories ==</option>
                <option v-for="category in categories" :value="category.id">{{ category.name}}</option>
            </select>
            <div class="alert alert-danger" v-if="errors && errors.category_id">
                {{ errors.title[0]}}
            </div>
            <br/>
            <input
                type="submit"
                :disabled="form_submiting"
                :value="form_submiting ? 'Saving Post...' : 'Save'"
                class="btn btn-primary"/>
        </form>
    </div>
</template>
<script>
export default {
    data(){
        return {
            categories:{},
            fields:{
                title:'',
                text:'',
                category_id:''
            },
            errors:{},
            form_submiting:false
        }
    },
    mounted() {
        axios.get('/api/category')
            .then(response => {
                this.categories = response.data.data;
            });
        axios.get('/api/posts/'+this.$route.params.id)
            .then(response => {
                this.fields = response.data.data;
            });
    },
    methods:{
        submit_form(){
            this.form_submiting=true;
            axios.put('/api/posts/'+this.$route.params.id,this.fields)
                .then(response =>  {
                    swal({
                        title:"Post Edited Successfully",
                        icon: "success",
                        button: "Close",
                    })
                    this.$router.push('/');
                    this.form_submiting = false;
                }).catch(error=>{
                if(error.response.status === 422){
                    swal({
                        title:"There is an error",
                        icon: "error",
                        button: "Close",
                    })
                    this.errors = error.response.data.errors;
                    this.form_submiting=false;
                }
            });
        }
    }
}
</script>

كود route للـ vue

import PostIndex from '../components/Posts/index';
import PostCreate from '../components/Posts/create';
import PostEdit from '../components/Posts/edit';


export default {
    mode: 'history',
    routes: [
        {
            path: '/',
            component: PostIndex,
            name: 'posts.index'
        },
        {
            path: '/posts/create',
            component: PostCreate,
            name: 'posts.create'
        },
        {
            path: '/posts/edit/:id',
            component: PostEdit,
            name: 'posts.edit'
        }
    ]
}


كود PostController

public function show(Post $post)
{
    return new PostResource($post);
}

public function update(StorePostRequest $request, Post $post)
{
    $post->update($request->validated());
    return new PostResource($post);
}


إضافة تعليق
Loading...