这可能是一件非常简单的事情,但是由于某些原因我无法弄清楚。我创建了一个从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>
目前我也无法做到这一点。尽管我不确定这是否是正确的方法,但我还是有些担心,一些随便的人可以使用隐藏的输入来添加他们想要的任何东西
答案 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)