【问题标题】:Image empty while updating image after succesful upload via Kartik FileInput Yii2 widget with Ajax method使用 Ajax 方法通过 Kartik FileInput Yii2 小部件成功上传后更新图像时图像为空
【发布时间】:2019-11-10 00:49:54
【问题描述】:

我有一个表格来更新我的新闻帖子,它在同一页面上有标题、内容和图片上传按钮。图片上传器使用 Kartik FileINput 小部件为 Yii2 应用 Ajax 方法。

这是我处理 AJAX 上传的 actionUpload

public function actionUpload($id)
{
$model = $this->findModel($id);
$currentImage=$model->image;
if (Yii::$app->request->isAjax) 
    {
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

            $image = $model->uploadImage();
            if($image===false)
                             {
                                  //echo "image instance is empty";
                                  $model->image = $currentImage; 
                            }

            if ($model->validate() && $model->save()) 
             {
                if($image !== false)
                    {
                  $model->image = $image->basename.'.'.$image->extension;
                $image->saveAs('uploads/batam/'.$model->image);
                $model->save(false);
                return \yii\helpers\Json::encode(array("image" => $model->image,
                    ));
                    }
             }
             else
                {echo "validation failed";}
    }
}

这是我在表单中提交的小部件文件上传(注意:它在活动表单内)

echo FileInput::widget([
    'name' => 'image',
    'options'=>[
        'multiple'=>false
    ],
    'pluginOptions' => [

         'uploadUrl' => Url::to(['news/upload','id'=>$id]),
         'uploadExtraData' => [
            'id'=>$id,
        ],
        'initialPreview'=>[
          Yii::getAlias('@web').'/uploads/batam'.$model->image
        ],
        'initialPreviewAsData'=>true,
        'overwriteInitial'=>false,
        'maxFileSize'=>2800
    ]
]);

这是我的模型规则和uploadImage方法

 public function rules()
    {
        return [
            [['title', 'content'], 'required'],
            [['content'], 'string'],
            [['created_at', 'updated_at'], 'safe'],
            [['image'], 'file','skipOnEmpty'=>true, 'extensions'=>'jpg,png,jpeg'],
            [['title'], 'string', 'max' => 255],
        ];
    }

    public function uploadImage() {
        $image = UploadedFile::getInstanceByName('image');
        if (empty($image)) {
            return false;
        }
        return $image;
    }

我有 2 个问题需要帮助: 1.验证规则不起作用。我可以上传任何具有任何扩展名的文件,并且它已成功上传并在数据库中更新 2. 图片上传包含在活动表单中,所以在使用 AJAX 成功上传后,当我按下“更新”按钮时,图片不会显示。 image 字段被视为空,因此 update 按钮的行为就像我更新了一个空图像。在我的数据库中,受人尊敬的news-id 的 AJAX 上传文件的图像路径已成功存储并且文件已上传。 如何解决这个问题?其实我不介意上传方法是否不使用AJAX,而只是使用post的普通单表单提交方法,因此省略了upload ajax按钮,但根据Kartik纪录片,如果我想使用显示先前存储的图像的小部件,它需要 Ajax。

我在 StackOverflow 等中查看了一些类似的问题,但是他们都在 Ajax 调用方法中遇到了空图像实例的问题(好吧,我以前遇到过同样的问题,但是在我之后我已经在我的 ajax 上应用了 Formdata研究),虽然我在ajax调用时没有空实例的问题,但在普通表单提交时是空实例。

这是我的行动更新

public function actionUpdate($id)
{
    $model = $this->findModel($id);
$image= UploadedFile::getInstanceByName('image');

 if ($model->load(Yii::$app->request->post()) && $model->save() ){
var_dump($image);exit();

            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,

            ]);
        }
}

提前致谢!

【问题讨论】:

    标签: php ajax yii2


    【解决方案1】:

    首先,验证器不起作用的原因是因为您没有从模型创建文件输入小部件,您必须这样做才能使类模型中的规则起作用:

    echo $form->field($model, 'image')->widget(FileInput::classname(), [
        'options' => ['accept' => 'image/*'],
    ]);
    

    那我不知道你的数据库的结构如何,但是我对如何处理图片上传的建议。首先,要在与数据库的图像字段分离的类中创建一个公共变量,这个公共图像变量将是实例化表单上的小部件的变量,也是具有规则的变量。这样,当您发布表单时,数据库中的图像字段将不会被覆盖。

    所以,当你使用 ajax 上传时,你也会发送对象的 id,并且在上传功能中,一旦设置好所有内容,你将存储路径,或者图像,或者任何东西在图像字段中数据库。

    【讨论】:

    • 您好,感谢您的回答。如果我按照您所说的那样回应小部件,它会起作用,但它不提供存储图像的初始预览。我需要根据 Kartik 文档按照上述方式进行操作。但是我也将代码的第一行更改为echo $form->field($model, 'image')->widget(FileInput::widget([ 'model'=>$model,,其他一切都一样,但是我得到了IE-10 browser error,我的浏览器不支持文件预览多文件上传。我正在使用最新的 chrome 顺便说一句,也在最新的歌剧中尝试过,但仍然遇到同样的错误
    • 至于结构,我没有单独的image 表,而是使news 表具有存储上传图像路径的image 列。您能否详细说明并提供一个关于您所说的简单示例:to create a public variable inside the class separated from the image field of the database, this public image variable will be the one that will instanciate the widget on the form ?谢谢@Josep Vidal
    • @codejunkie 它不会提供初始图像,因为模型图像的值为空,因此在渲染组件时没有图像,为了显示预览图像,您可以加载默认图像在渲染之前的控制器中。在呈现表单的控制器内部,加载模型类后,您可以执行类似 $model->image = "default-path-to-image.jpg" 的操作。您可以在没有模型的情况下创建图像输入,但是模型内部的规则将不适用于输入表单。
    • 是的@codejunkie,从我的一个repos中检查这个模型:github.com/jvidalv/dishora/blob/master/models/Empresa.php,查看名称为$foto的公共变量,它不是数据库中的一行,我只使用它呈现表单并检索图像。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 2018-12-21
    相关资源
    最近更新 更多