如何获取变量以显示在商店功能中

时间:2019-01-16 10:30:39

标签: laravel vue.js

这可能是一件非常简单的事情,但是由于某些原因我无法弄清楚。我创建了一个从vue组件获取图像的函数。 我想做的是从postImage()中获取图像,并将其放入store()函数中,以便将所有内容保存到数据库中。 我遇到的问题是,当我收到此错误消息

  

函数App \ Http \ Controllers \ Admin \ CategoryController :: store()的参数太少,传递了1个参数,而恰好是2个参数

我确实知道该错误告诉我,仅发送了$request,而不发送了$image。我不确定如何使它工作。如果我遗漏了任何东西,请告诉我

这是我的控制人

public function store(Request $request, $image)
{

    $category = new Category();

    $input = $this->safeInput($request);

    $category->fill($input);

    dd($image);

    $slug = $category->slug($category->title);
    $category->slug = $slug;

    if($request->has('active'))
    {
        $category->active = 1;
    }else{
        $category->active = 0;
    }

    $category_order = $category->order_number();
    $category->order = $category_order;

    $category->save();
}

public function postImage(Request $request)
{

    if($request->hasFile('image'))
    {
        $names = [];
        foreach($request->file('image') as $image)
        {
            $destinationPath = 'product_images/category/';
            $filename = $image->getClientOriginalName();
            $image->move($destinationPath, $filename);
            array_push($names, $filename);          
        }

        $image = json_encode($names);
        return $image;
    }
}

这是我的Vue组件

<template>
    <div class="container">
        <div class="uploader"
            @dragenter="OnDragEnter"
            @dragleave="OnDragLeave"
            @dragover.prevent
            @drop="onDrop"

        >

            <div v-show="!images.length" :value="testing()">
                <i class="fas fa-cloud-upload-alt"></i>
                <div>OR</div>
                <div class="file-input">
                    <label for="file">Select a file</label>
                    <input type="file" id="file" @change="onInputChange" multiple>
                </div>
            </div>

            <div class="images-preview" v-show="images.length">
                <div class="img-wrapper" v-for="(image, index) in images">
                    <img :src="image" :alt="`Image Uplaoder ${index}`">

                    <div class="details">
                        <span class="name" v-text="files[index].name"></span>
                        <span class="size" v-text="getFileSize(files[index].size)"></span>
                    </div>

                    <div class="btn btn-danger" @click="funDeleteFile(index)">
                        Remove
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        mounted() {
            console.log('Component mounted.')
        },

        data() {
            return {
                isDragging: false,
                //Sets the dragCount to 0
                dragCount: 0,
                //Makes files an array, so that we can send the files to the server
                files: [],
                //Makes images an array, so that we can let the user see the images
                images: [],
            }
        },

        methods: {
            testing() {
                console.log('This is submit images - '+this.files);

                var formData = new FormData();
                this.files.forEach(file => {
                    formData.append('image[]', file, file.name);
                }); 

                axios.post('/admin/category/post-image', formData);
            },

            OnDragEnter(e) {
                //Prevents the default action of the browser
                e.preventDefault();

                // This lets the dragCount become 1, so that the image uploader changes colour
                this.dragCount++;

                // Changes the isDragging variable to true instead of false
                this.isDragging = true;

                return false;
            },

            OnDragLeave(e) {
                //Prevents the default action of the browser
                e.preventDefault();

                // This lets the dragcount become 0, so that the image uploader changes to it's original colour
                this.dragCount--;

                // This is if the dragCount is <= 0 then the isDragging variable is false
                if (this.dragCount <= 0)
                    this.isDragging = false;
            },

            onInputChange(e) {
                // Grabs the files from the event
                const files = e.target.files;

                // Creates an array for files, so that we can loop thru it
                // Send the file to the addImage method via "this.addImage(file)"
                Array.from(files).forEach(file => this.addImage(file));
            },

            onDrop(e) {
                //Prevents the default action of the browser
                e.preventDefault();

                //Stops the propagation into the other elements inside the one we drop and file into
                e.stopPropagation();

                // This is to disable the dragging of the images
                this.isDragging = false;

                // Grabs the files from the event
                const files = e.dataTransfer.files;

                // Creates an array for files, so that we can loop thru it
                // Send the file to the addImage method via "this.addImage(file)"
                Array.from(files).forEach(file => this.addImage(file));
            },

            addImage(file) {
                //Checks if the file type is an image
                if (!file.type.match('image.*')) {
                    this.$toastr.e(`${file.name} is not an image`);
                    return;
                }

                this.files.push(file);

                const img = new Image(),

                reader = new FileReader();
                reader.onload = (e) => this.images.push(e.target.result);
                reader.readAsDataURL(file);



            },


        }
    }
</script>

我的create.blade.php

@extends('layouts.admin')
@section('content')
    @component('admin.components.products.category-form', [
                'formUrl' => route('category.store'),
                'formMethod' => 'POST',
                'model' => $category,
                'category_id' => $category_id,
                'image' => '',
                'image2' => ''
            ])
    @endcomponent
@endsection

和我的表格

{{ Form::model($model, array('url' => $formUrl, 'method' => $formMethod, 'class' => 'add-form', 'files' => true)) }}
    <div class="form-group">
        {{ Form::label('category_id', 'Parent Category') }}
        {{ Form::select('category_id', $category_id->prepend('Please Select', '0'), null, array('class' => 'form-control')) }}
    </div>

    <div class="form-group">
        {{ Form::label('title', 'Title') }}
        {{ Form::text('title', null, array('class' => 'form-control')) }}
    </div>

    <div class="form-group">
        <label>Active:</label>
        {{ Form::checkbox('active', 0) }}
    </div>

    <div id="app" class="mb-20">
        <category-image></category-image>
    </div>

    <div class="form-group">
        {{ Form::submit('Save', array('class' => "btn btn-dark btn-lg btn-block")) }}
    </div>
{{ Form::close() }}

我的路线

Route::resource('admin/category', 'Admin\CategoryController');
Route::post('admin/category/post-image', 'Admin\CategoryController@postImage')->name('admin.category.post-image');

更新

我已经尝试过将图像传递到表单中的隐藏字段,以便可以在存储功能的$ request中获取它。

在我的CategoryController @ create

$category = new Category();

$category_list = Category::with('parentCategory')->get();
$category_id = Category::pluck('title', 'id');
// I've added this.
$image = '';

return view('admin.products.category.create', compact('category', 'category_list', 'category_id', 'image'));

在我的CategoryController @ postImage

//I've added this to, so that I can pass the image variable to the create.blade.php
return redirect()->route('category.create', compact('image'));

然后在我添加的create.blade.php中

'my_image' => $my_image

,并且在我添加的category-form.blade.php组件中

<div id="app" class="mb-20">
    <category-image></category-image>
    <input type="hidden" name="image" id="image" value="{{ $my_image }}">
</div>

目前我也无法做到这一点。尽管我不确定这是否是正确的方法,但我还是有些担心,一些随便的人可以使用隐藏的输入来添加他们想要的任何东西

4 个答案:

答案 0 :(得分:0)

对于$ image,您有什么参数?在您的axios.post中未指定。

public function store(Request $request)
{

    $category = new Category();

    $input = $this->safeInput($request);

    $category->fill($input);

    dd($this->postImage($request));

    $slug = $category->slug($category->title);
    $category->slug = $slug;

    if($request->has('active'))
    {
        $category->active = 1;
    }else{
        $category->active = 0;
    }

    $category_order = $category->order_number();
    $category->order = $category_order;

    $category->save();
}

public function postImage($request)
{

    if($request->hasFile('image'))
    {
        $names = [];
        foreach($request->file('image') as $image)
        {
            $destinationPath = 'product_images/category/';
            $filename = $image->getClientOriginalName();
            $image->move($destinationPath, $filename);
            array_push($names, $filename);          
        }

        $image = json_encode($names);
        return $image;
    }
}

答案 1 :(得分:0)

在create.blade中,您使用'formUrl'=> route('category.store'),此路由调用“ store”方法,对吗?如果是这样,它还需要传递$ image参数。如果我们也可以获取您的Web路由文件,则更容易发现问题。

如果route('category.store')确实调用了store方法,那么您有几个选择。

1-如果您真的不需要$ image参数作为store方法,则可以将其删除。

2-如果在某些情况下需要使用它,则只需将参数设置为可选,然后在处理该参数之前检查它是否已收到。示例:store(Request $ request,$ image = null)

3-如果确实需要此参数,则即使在调用路由时,也必须每次都传递它。示例:route('category.store',['image'=> $ something])。现在在create.blade中查看代码,虽然您没有要传递的内容,所以我认为这不是一个选择。

答案 2 :(得分:0)

如果$ request在那里可用,则无需传递额外的$ image变量。 你尝试过

dd($request)

print_r($request->toArray()); exit; 看看您的要求是什么!

答案 3 :(得分:0)

问题不是通过表单发送的请求对象中缺少图像,这是category.store方法所需的第二个参数。

即使您现在以带有隐藏字段的形式发送图像,每次调用category.store时,仍需要将其作为参数传递。

您的存储方法的定义类似于

store(Request $request, $image)

因此,当您调用此方法时,即使仅使用route('category.store')获取路线URL,也需要在此调用中发送image参数。 示例:

route('category.store', ['image' => 'image id here']);

您的Web路由文件中的路由定义也是如此。您正在使用资源路由,但是laravel期望默认资源中的store方法没有第二个参数,因此您需要更改它。

/*
adds exception to the resource so it will not handle the store method
*/
Route::resource('admin/category', 'Admin\CategoryController')->except(['store']);

//adds a custom route that supports the $image parameter.
Route::post('admin/category/{image}', 'Admin\CategoryController@store')

现在,如果您打算通过请求对象发送图像,则不需要将它作为第二个参数,因此您唯一需要更改的就是使您的category.store方法像这样。

public function store(Request $request)