【问题标题】:How do I get my variable to show in my store function如何让我的变量显示在我的商店功能中
【发布时间】:2019-01-17 21:56:07
【问题描述】:

这可能是一件非常简单的事情,但由于某种原因我无法弄清楚。我创建了一个从我的 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>

目前我也无法做到这一点。虽然我不确定这是否是正确的方法,但我有点担心一些随机的人可以使用隐藏的输入添加他们想要的任何内容

【问题讨论】:

  • store 方法中删除$image。我不认为你在任何地方都在store 方法中使用它
  • 从哪里传递$imagestore 函数?该错误表明您没有将第二个参数传递给存储函数,即$image
  • 不清楚你想做什么描述问题

标签: laravel vue.js


【解决方案1】:

你有什么参数$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;
    }
}

【讨论】:

  • 我以为FormData通过了图片
  • dd($this-&gt;postImage($request)); 也传递了一个空值
【解决方案2】:

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

dd($request)

print_r($request-&gt;toArray()); exit; 看看你的要求是什么!

【讨论】:

  • 当我这样做时,我只会得到 category_id 和 title
  • 设置名称为[input type="file"]
【解决方案3】:

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

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

1 - 如果你真的不需要 store 方法的 $image 参数,你可以删除它。

2 - 如果您在少数情况下需要它,只需将参数设为可选并在处理之前检查它是否已收到。示例:store(Request $request, $image = null)

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

【讨论】:

  • 我已将路线添加到我的问题中。
  • 我确实需要传递我的图像,因为它是必需的。在将我的 $image 拖到图像组件后,我曾想过尝试将其传递给我的刀片,但我没有设法做到这一点。我已经更新了我的问题,说出我尝试过的内容
  • 我已根据您的新信息发送了另一个答案。
【解决方案4】:

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

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

你的 store 方法被定义为

store(Request $request, $image)

因此,当您调用此方法时,即使您只是通过 route('category.store') 获取路由 URL,您也需要在此调用中发送图像参数。 示例:

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

您的网络路由文件中的路由定义也是如此。您正在使用资源路由,但 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)

【讨论】:

  • 如果我这样做public function store(Request $request),那么我该如何将图像与表单的其余部分一起保存?由于图像是一个 vue 组件,根据我的理解(在我的情况下),没有办法抓取图像并将其添加到 $request
猜你喜欢
  • 2020-10-28
  • 2016-10-15
  • 1970-01-01
  • 2019-11-06
  • 2022-12-15
  • 1970-01-01
  • 1970-01-01
  • 2021-04-12
  • 1970-01-01
相关资源
最近更新 更多