2014-12-09 5 views
3

настоящее время я использую MEAN.js создать приложение, и я scaffolded простой объект, называемый кампании. Я хотел бы, чтобы каждая кампания имела связанное изображение. Поэтому я хотел бы изменить интерфейс CRUD, чтобы иметь возможность загрузить файл в конец.MEAN стек нг-загрузки-файлов

Я ввел нг-файл загрузите плагин для создания FE с угловыми. На стороне Node.js я установил плагин multer, чтобы помочь мне сохранить файл в папке (например, ./uploads). Дело в том, что я не совсем понял поток, и я надеялся на предложение.

Пожалуйста, найдите ниже точки зрения:

<section data-ng-controller="CampaignsController"> 
    <div class="page-header"> 
     <h1>New Campaign</h1> 
    </div> 
    <div class="col-md-12"> 
     <form class="form-horizontal" data-ng-submit="create()" novalidate> 
      <fieldset> 
       <div class="form-group"> 
        <label class="control-label" for="name">Name</label> 
        <div class="controls"> 
         <input type="text" data-ng-model="name" id="name" class="form-control" placeholder="Name" required> 
        </div> 
       </div> 
       <div class="form-group"> 
        <button ng-file-select ng-model="token">Upload the token</button> 
        <div ng-file-drop ng-model="token" class="drop-box" 
         drag-over-class="{accept:'dragover', reject:'dragover-err', delay:100}" 
         accept="image/*"> 
           Drop image file here 
        </div> 
        <div ng-no-file-drop>Image drop is not supported for this browser.</div> 
       </div> 
       <div class="form-group"> 
        <input type="submit" class="btn btn-default"> 
       </div> 
       <div data-ng-show="error" class="text-danger"> 
        <strong data-ng-bind="error"></strong> 
       </div> 
      </fieldset> 
     </form> 
    </div> 
</section> 

Затем Угловая действие контроллера:

// Create new Campaign 
    $scope.create = function() { 
     // Create new Campaign object 
     var campaign = new Campaigns ({ 
      name: this.name 
     }); 

     $scope.$watch('token', function() { 
      $scope.upload = $upload.upload({ 
       url: '/campaigns', //upload.php script, node.js route, or servlet url 
       method: 'POST', //Post or Put 
       headers: {'Content-Type': 'multipart/form-data'}, 
       //withCredentials: true, 
       data: campaign, //from data to send along with the file 
       file: $scope.token, // or list of files ($files) for html5 only 
       //fileName: 'photo' // to modify the name of the file(s)     
      }).success(function (response, status) { 
       // Redirect after save 
       campaign.$save(function(response) { 
        $location.path('campaigns/' + response._id); 

        // Clear form fields 
        $scope.name = ''; 
       }, function(errorResponse) { 
        $scope.error = errorResponse.data.message; 
       }); 
      } 
      ).error(function (errorResponse) { 
       $scope.error = errorResponse.data; 
       //$scope.error = errorResponse.data.message; 
      }); 
     }); 
    }; 

Наконец, Node.js контроллер часть:

var mongoose = require('mongoose'), 
     errorHandler = require('./errors'), 
     multer = require('multer'), 
     Campaign = mongoose.model('Campaign'), 
     _ = require('lodash'); 

    /** 
    * Create a Campaign 
    */ 
    exports.create = function(req, res) { 
     var campaign = new Campaign(req.body); 
     campaign.user = req.user; 

     multer({ 
      dest: './uploads/' 
     }); 

     campaign.save(function(err) { 
      if (err) { 
       return res.status(400).send({ 
        message: errorHandler.getErrorMessage(err) 
       }); 
      } else { 
       res.jsonp(campaign); 
      } 
     }); 
    }; 

Прямо сейчас , что происходит, так это то, что - когда я пытаюсь загрузить файл - загрузчик не ждет, пока файл будет выбран, но он немедленно отправляет запрос POST (почему?). Более того, я получаю ответ 400.

Любое предложение было бы действительно оценено!

Благодаря Приветствия

+0

на вашей $ watch функции убедитесь, что токен не пуст. Если файл очищен, все равно будет изменение, и, возможно, это причина, по которой он отправляет сообщение, когда вы нажимаете на select перед его фактическим выбором. – danial

+0

Думаю, вам лучше разместить его в github плагина, поскольку он очень специфичен для этого плагина, или, по крайней мере, пометить его именем плагина. – danial

+0

Есть несколько примеров nodejs плагина, в котором вы можете найти ссылку в документах. это может помочь вам. – danial

ответ

0

я частично решить эту проблему.

Это новый вид:

<section data-ng-controller="CampaignsController"> 
    <div class="container"> 
     <div class="page-header"> 
      <h1>New Campaign</h1> 
     </div> 
     <div class="col-sm-12 col-md-4 col-md-offset-4"> 
      <form class="form-horizontal" data-ng-submit="create(token)" novalidate> 
       <fieldset> 
        <div class="form-group"> 
         <label class="control-label" for="name">Name</label> 
         <div class="controls"> 
          <input type="text" data-ng-model="name" id="name" class="form-control" placeholder="Name" required> 
         </div> 
        </div> 
        <div class="form-group"> 
         <label class="control-label" for="token">Token</label> 
         <div class="controls"> 
          <input type="file" id="token" ng-file-select ng-model="token"/> 
          <p class="help-block">The token file must be a squared .png or .jpg image.</p> 
         </div> 
        </div> 
        <div class="form-group"> 
         <div class="controls"> 
          <input type="submit" class="btn btn-default col-xs-12"> 
         </div> 
        </div> 
        <div class="form-group"> 
         <div data-ng-show="error" class="control alert alert-danger alert-dismissible" role="alert"> 
          <span data-ng-bind="error"></span> 
         </div> 
        </div> 
       </fieldset> 
      </form> 
     </div> 
    </div> 
</section> 

Затем Угловое действие контроллера:

$scope.create = function(token) { 
     // Create new Campaign object 
     var campaign = new Campaigns ({ 
      name: this.name 
     }); 

     $scope.upload = $upload.upload({ 
      url: '/campaigns', 
      method: 'POST', 
      headers: {'Content-Type': 'multipart/form-data'}, 
      //withCredentials: true, 
      data: { 
       campaign: JSON.stringify(campaign) 
      }, 
      file: token, 
      //fileName: 'token' // to modify the name of the file     
     }).success(function (response, status) { 
       // Redirect after save 
       $location.path('campaigns/' + response._id); 

       // Clear form fields 
       $scope.name = ''; 
       $scope.token = ''; 
      } 
     ).error(function (errorResponse) { 
       $scope.error = errorResponse.data; 
      } 
     ); 
    }; 

Я теперь с помощью узла многопартийного для контроллера Node.js:

экспорт. create = function (req, res) {

var form = new multiparty.Form(); 
form.parse(req, function(err, fields, files) { 
    //res.writeHead(200, {'content-type': 'text/plain'}); 
    //res.end(util.inspect({fields: fields, files: files})); 
    var file = files.file[0]; 
    var contentType = file.headers['content-type']; 
    var tmpPath = file.path; 
    var extIndex = tmpPath.lastIndexOf('.'); 
    var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex); 
    // uuid is for generating unique filenames. 
    //var fileName = uuid.v4() + extension; 
    var fileName = tmpPath; 
    var destPath = 'uploads/' + fileName; 

    // Server side file type checker. 
    if (contentType !== 'image/png' && contentType !== 'image/jpeg') { 
     fs.unlink(tmpPath); 
     return res.status(400).send({ 
      message: 'Unsupported file type' 
     }); 
    } 

    fs.rename(tmpPath, destPath, function(err) { 
     if (err) { 
      return res.status(400).send({ 
       message: 'Image is not saved' 
      }); 
     } 
     fs.unlink(tmpPath, function() { 
      if (err) { 
       return res.status(400).send({ 
        message: 'Impossible to delete temp file' 
       }); 
      } 
     }); 
     console.log(destPath); 
     //return res.jsonp(destPath); 
    }); 

    var campaign = new Campaign(JSON.parse(fields.campaign[0])); 
    campaign.user = req.user; 

    campaign.save(function(err) { 

     if (err) { 
      return res.status(400).send({ 
       message: errorHandler.getErrorMessage(err) 
      }); 
     } else { 
      res.jsonp(campaign); 
     } 
    }); 
}); 

};

У меня все еще есть ошибка, но я не думаю, что это связано с загрузкой файла. Как вы думаете?

/home/maurizio/Workspace/bdf-v1/node_modules/mongoose/lib/utils.js:413 throw err; ^ Ошибка: не удается установить заголовки после их отправки. в ServerResponse.OutgoingMessage.setHeader (http.js: 691: 11) на сервере ServerResponse.header (/home/maurizio/Workspace/bdf-v1/node_modules/express/lib/response.js:592:10) на сервере Server Response .send (/home/maurizio/Workspace/bdf-v1/node_modules/express/lib/response.js:144:12) в ServerResponse.jsonp (/ home/maurizio/Workspace/bdf-v1/node_modules/express/lib /response.js:301:15) в Promise. (/ дом/Maurizio/Workspace/BDF-v1/приложение/контроллеры/кампании.server.controller.js: 67: 9) в Promise. (/home/maurizio/Workspace/bdf-v1/node_modules/mongoose/node_modules/mpromise/lib/promise.js:177:8)

0

Использование res.status (400) .send ... или res.jsonp() отправит данные обратно клиенту, начиная с заголовков. В вашем скрипте эти утверждения проваливаются, но последующие не могут быть выполнены, поскольку данные уже отправлены клиенту.

Возврат, который у вас есть, завершит выполнение метода, в котором они вызывается, но сценарий будет просто продолжать следующий метод, когда он встретит другую функцию express send(). В вашем случае fs.rename отправит() 400, но столкнутся с другой отправкой(), когда он достигнет метода campaign.save, где он выкинет ошибку.

Возьмите вызовы с возвратом res.status (400) .send() и вместо этого установите сообщение как строковую переменную и вызовите вызов res.status (400) .send() в заключительном условном выражении if ошибка присутствует.

По существу, убедитесь, что вызов send() или jsonp() может быть выполнен только один раз в вашем скрипте.