2015-03-27 21 views
5

này được tình hình: Tôi mới vào Yii2 và muốn sử dụng một số phụ tùng tập tin tải lên trong vòng ActiveForm .. cho đến nay tôi đã tìm thấy xuất sắc này một: \kartik\widget\FileInputyii2 - nộp Kartik đầu vào - cập nhật

Với điều này widget Tôi có thể quản lý tải lên tập tin và sau đó, khi vào chế độ chỉnh sửa, hiển thị hình ảnh đã tải lên trước đó với oportunite để thay thế nó.

Vấn đề là nếu tôi nhấn nút "Cập nhật" của biểu mẫu mà không sửa đổi hình ảnh yii nói rằng hình ảnh "không thể trống" vì tôi đã đặt quy tắc 'bắt buộc' trong mô hình của mình.

Trả lời

5

Sau một buổi chiều khủng khiếp và một đêm năng suất cao hơn, tôi đã gặp phải một giải pháp mà làm việc cho tôi ..

Vấn đề chính là tập tin đầu vào không gửi giá trị (tên của tập tin lưu trữ trong cơ sở dữ liệu) khi cập nhật. Nó chỉ gửi thông tin hình ảnh nếu được duyệt và được chọn thông qua đầu vào tệp ..

Vì vậy, giải pháp của tôi đã tạo một trường "ảo" khác để quản lý tải lên tệp có tên "upload_image". Để đạt được điều tôi đơn giản này thêm một tài sản công khai với tên này đến lớp mô hình của tôi: public $upload_image;

Tôi cũng thêm xác nhận folowing phương pháp quy định về lớp mẫu:

public function rules() 
{ 
    return [ 
     [['upload_image'], 'file', 'extensions' => 'png, jpg', 'skipOnEmpty' => true], 
     [['image'], 'required'], 
    ]; 
} 

Ở đây, 'upload_image' là ảo của tôi cột. Tôi đã thêm xác nhận 'tệp' với 'skipOnEmpty' = true và 'hình ảnh' là trường trên cơ sở dữ liệu của tôi, điều đó phải được yêu cầu trong trường hợp của tôi.

Sau đó, theo quan điểm của tôi, tôi cấu hình 'upload_image' phụ tùng thích sau:

echo FileInput::widget([ 
     'model' => $model, 
     'attribute' => 'upload_image', 
     'pluginOptions' => [ 
      'initialPreview'=>[ 
       Html::img("/uploads/" . $model->image) 
      ], 
      'overwriteInitial'=>true 
     ] 
    ]); 

Trong tùy chọn 'initialPreview' Tôi asign tên hình ảnh của tôi, lưu trữ trong '$ model-> hình ảnh' bất động sản trở về từ cơ sở dữ liệu.

Cuối cùng, bộ điều khiển của tôi trông giống như sau:

public function actionUpdate($id) 
{ 
    $model = $this->findModel($id); 
    $model->load(Yii::$app->request->post()); 

    if(Yii::$app->request->isPost){ 
     //Try to get file info 
     $upload_image = \yii\web\UploadedFile::getInstance($model, 'upload_image'); 

     //If received, then I get the file name and asign it to $model->image in order to store it in db 
     if(!empty($upload_image)){ 
      $image_name = $upload_image->name; 
      $model->image = $image_name; 
     } 

     //I proceed to validate model. Notice that will validate that 'image' is required and also 'image_upload' as file, but this last is optional 
     if ($model->validate() && $model->save()) { 

      //If all went OK, then I proceed to save the image in filesystem 
      if(!empty($upload_image)){ 
       $upload_image->saveAs('uploads/' . $image_name); 
      } 

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

Hãy thử tải trước trường nhập tập tin với nội dung của trường đó. Bằng cách này, bạn sẽ không mất dữ liệu sau khi gửi biểu mẫu của mình.

Tôi nhìn qua kartik file-input widget (thoải mái tìm kiếm, btw) và tôi đi qua một cách để làm điều này

// Display an initial preview of files with caption 
// (useful in UPDATE scenarios). Set overwrite `initialPreview` 
// to `false` to append uploaded images to the initial preview. 
echo FileInput::widget([ 
    'name' => 'attachment_49[]', 
    'options' => [ 
     'multiple' => true 
    ], 
    'pluginOptions' => [ 
     'initialPreview' => [ 
      Html::img("/images/moon.jpg", ['class'=>'file-preview-image', 'alt'=>'The Moon', 'title'=>'The Moon']), 
      Html::img("/images/earth.jpg", ['class'=>'file-preview-image', 'alt'=>'The Earth', 'title'=>'The Earth']), 
     ], 
     'initialCaption'=>"The Moon and the Earth", 
     'overwriteInitial'=>false 
    ] 
]); 

Bạn cũng có thể muốn thư giãn required quy tắc trong mô hình của bạn cho lĩnh vực đó, vì vậy nó không khiếu nại về xác nhận. Bạn có thể chọn nhắc người dùng thông qua công cụ phụ.

3

Tôi đã gặp phải một giải pháp khác bằng cách tạo kịch bản. Trong trường hợp của bạn, tôi sẽ sửa đổi các quy tắc như sau:

public funtion rules() { 
    [['image'], 'file'], 
    [['image'], 'required', 'on'=> 'create'] 
} 

Vì vậy, trường tải lên tệp sẽ chỉ được yêu cầu trong hành động tạo. Trong hành động cập nhật, tôi có mã này:

public function actionUpdate($id) 
    { 
     $model = $this->findModel($id); 

     if ($model->load(Yii::$app->request->post())) { 

      $newCover = UploadedFile::getInstance($model, 'image'); 

      if (!empty($newCover)) { 
      $newCoverName = Yii::$app->security->generateRandomString(); 
      unlink($model->cover); 
      $model->cover = 'uploads/covers/' . $newCoverName . '.' . $newCover->extension; 
      $newCover->saveAs('uploads/covers/' . $newCoverName . '.' . $newCover->extension); 
      } 

      if ($model->validate() && $model->save()) { 
      return $this->redirect(['view', 'id' => $model->post_id]); 
      } else { 
      // error saving model 
      } 

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

    } 

Trong trường hợp cập nhật hình ảnh không yêu cầu nhưng mã kiểm tra nếu không có gì được tải lên và không thay đổi giá trị trước đó.

tập tin hình thức của tôi:

<?= $form->field($model, 'image')->widget(FileInput::classname(), [ 
    'options' => ['accept'=>'image/*'], 
    'pluginOptions'=>[ 
     'allowedFileExtensions'=>['jpg', 'gif', 'png', 'bmp'], 
     'showUpload' => true, 
     'initialPreview' => [ 
      $model->cover ? Html::img($model->cover) : null, // checks the models to display the preview 
     ], 
     'overwriteInitial' => false, 
    ], 
]); ?> 

tôi nghĩ là dễ dàng hơn một chút so với một lĩnh vực ảo. Hy vọng nó giúp!

-2

Từ Krajee:

http://webtips.krajee.com/advanced-upload-using-yii2-fileinput-widget

Tạo, xóa, cập nhật: thực sự dễ dàng, không lựa chọn nào hơn nữa.

(1) Tôi cũng đã đặt quy tắc 'bắt buộc' trong mô hình của mình.

(2) Để làm việc trên Wampserver:

Yii::$app->params['uploadPath'] = Yii::$app->basePath . '/web/uploads/'; 

Yii::$app->params['uploadUrl'] = Yii::$app->urlManager->baseUrl . '/uploads/'; 
Các vấn đề liên quan