2016-08-11 4 views
0

My AngularJSモデルには、ファイルオブジェクトvm.profile.fileと、サーバー上のアップロードされたファイルへの参照を含むテキスト値の2つのプロパティがあります。vm.profile.resumevm.profile.fileは、制限されたサイズで必要に応じて検証されます。しかし、フォームが更新されているときに、受け入れられてサーバーに渡される参照は正常ですが、サーバーにファイルオブジェクトを再度設定する必要はありません。不要なファイルオブジェクトが空のときにファイルへの参照が存在する場合、フォームを検証するにはどうすればよいですか?ここでフォームウィジェット内に既にアップロードされているファイルのAngularJSでの検証を管理するにはどうすればよいですか?

I'm using ng-file-upload.

フォームは次のようになります。ここでは enter image description here

私が使用しているコードの一部です:

<div class="sj-section-content" flex="60"> 
     <md-card> 
      <md-input-container> 
       <div layout="row" layout-align="start center"> 
        <md-button class="md-primary md-raised" 
           style="max-width: 150px; color: white;" 
           ngf-select 
           required 
           name="resume" 
           ngf-min-size="0MB" 
           ngf-max-size="1MB" 
           ng-model="vm.profile.file"> 
         <span>{{!vm.profile.resume ? 'Select file' : 'Change'}}</span> 
        </md-button> 
        <md-button ng-if="vm.profile.resume" ng-click="vm.profile.file = {}" class="md-icon-button"> 
         <md-icon md-font-icon="clear">clear</md-icon> 
        </md-button> 
       </div> 
       <div ng-if="vm.profile.file.name" layout="row" layout-align="start center"> 
        <md-button class="md-icon-button" md-no-ink> 
         <md-icon md-font-icon="attachment">attachment</md-icon> 
        </md-button> 
        <div>{{vm.profile.file.name}}</div> 
       </div> 
       <div ng-messages="profileForm.resume.$error" 
        ng-if="profileForm.resume.$error && (profileForm.$submitted || profileForm.resume.$dirty)" 
        role="alert"> 
        <div ng-if="profileForm.resume.$error.maxSize" 
         ng-message="maxSize">Max file size is 10MB</div> 
        <div ng-if="profileForm.resume.$error.required" 
         ng-message="required">Resume is a required field</div> 
       </div> 
      </md-input-container> 
     </md-card> 
    </div> 

をAPIサービス:

ProfileApi.prototype.update = function update(model) { 
     var deferred = $q.defer(); 

     Upload.upload({ 
      url: endpoint, 
      method: 'PUT', 
      data: model 
     }).then(function success(response) { 
      deferred.resolve(response.data); 
     }, function error(response) { 
      deferred.reject(response.data); 
     }); 

     return deferred.promise; 
    }; 

およびサーバー上:

exports.fileHandler = function(req, res, next) { 
    var MAX_FILE_SIZE = 10 * 1000000; 
    var FILE_FIELD = 'file'; 
    var PARENT_DIRECTORY = 'files/resumes/'; 

    // Validate here 
    var fileFilter = function fileFilter (req, file, callback) { 
     // allowed extensions .doc .docx .odt .pdf .txt 
     var allowedMimeTypes = [ 
      'application/msword', 
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 
      'application/vnd.oasis.opendocument.text', 
      'application/pdf', 
      'text/plain' 
     ]; 
     var validMimetype = allowedMimeTypes.some(function(mimetype) { 
      return file.mimetype == mimetype; 
     }); 

     if (!validMimetype) return callback(new Error('Resume is not a valid file format')); 

     callback(null, true) 
    }; 

    var fileOptions = { 
     fileFilter: fileFilter, 
     dest: 'tmp/', 
     limits: { 
      fileSize: MAX_FILE_SIZE 
     } 
    }; 
    var upload = multer(fileOptions).single(FILE_FIELD); 

    upload(req, res, function(err) { 
     if (err) return res.status(400).send({message: err.message}); 

     // We don't need a new file if req.body.resume has a value 
     console.log(typeof req.body.resume); 
     if (_.isEmpty(req.body.resume) && typeof req.file === 'undefined') { 
      return res.status(400).send({message: 'Resume file is required'}); 
     } 

     // Make sure that if there is a resume file but no new file, the resume exists in the file system. 
     if (req.body.resume && typeof req.file === 'undefined') { 
      fs.stat('client/' + req.body.resume, function(err, stats) { 
       if (err) { 
        return res.status(400).send({message: 'Resume doesn\'t exist on file server'}); 
       } else { 
        return next(); 
       } 
      }) 
     } else { 
      // Let's add the file path at req.body.resume. 
      // The idea is that if the save method on the model returns and error. Delete the file 
      // in the tmp folder. Then return an error. If the model validates and is saved. Move the 
      // file into the proper folder 

      req.body.resume = PARENT_DIRECTORY + req.user._id + '/' + req.file.originalname; 
      return next(); 
     } 
    }); 
}; 

更新制御方法であって、ファイル・フィールドに

exports.update = function(req, res) { 
    var crewListing = req.app.locals.crewListing; 

    // Protect information 
    delete req.body.author; 
    delete req.body.__v; 
    delete req.body._id; 

    // Merge objects 
    _.merge(crewListing, req.body); 

    crewListing.save({runValidators: true}, function(err, result) { 
     if (req.file) { 
      if (err) { 
       // Delete the req file 
       fs.unlink(req.file.path, function() { 
        return res.status(400).send(validationErrorHandler(err,true)); 
       }); 
      } else { 
       // Move the req file 
       console.log(req.file); 
       fs.move(req.file.path, 'client/' + crewListing.resume, {clobber: true}, function(err) { 
        if (err) return res.status(400).send({message: 'Unexpected error has occured'}) 
        return res.json(result); 
       }); 
      } 
     } else { 
      if (err) return res.status(400).send(validationErrorHandler(err, true)); 
      return res.json(result); 
     } 
    }) 
}; 

答えて

0

NG-必要な指令は、条件付きであってもよいです。レジュームテキストフィールドに値がある場合、ファイルフィールドは必須ではありません。

ng-required="!vm.profile.resume" 
関連する問題