2014-04-08 39 views
18

我最近開始用MEAN Stack進行編程,而且我正在實現某種社交網絡。一直使用MEAN.io框架來做到這一點。 我現在的主要問題是讓文件上載工作,因爲我想要做的就是將文件從表單接收到AngularJS Controller中,並將其與更多信息一起傳遞給ExpressJS,以便我最終可以將所有內容發送到MongoDB。 (我正在建立一個註冊新用戶表格)。意味着堆棧文件上傳

我不想將文件本身存儲在數據庫中,但我想存儲一個鏈接。

我在谷歌搜索了幾十頁不同的搜索查詢,但我找不到任何我能理解或工作的東西。一直在尋找幾個小時,但沒有結果。這就是我來到這裏的原因。

任何人都可以幫助我嗎?

謝謝:)

編輯:也許有點代碼會幫助理解。

默認MEAN.io用戶,我使用爲基礎,其角控制器具有這樣的:

$scope.register = function(){ 
     $scope.usernameError = null; 
     $scope.registerError = null; 
     $http.post('/register', { 
      email: $scope.user.email, 
      password: $scope.user.password, 
      confirmPassword: $scope.user.confirmPassword, 
      username: $scope.user.username, 
      name: $scope.user.fullname 
     })//... has a bit more code but I cut it because the post is the main thing here. 
    }; 

我想要做的是: 從形式接收文件,在此控制器,並將其傳遞以及電子郵件,密碼,名稱等等,並能夠在位於服務器端的expressjs上使用json。 '/ register'是一個nodejs路由,因此是一個服務器控制器,它創建用戶(用戶模式)並將其發送到MongoDB。

+0

Mean-upload已被廢棄,現在稱爲「上傳」。它是在 - https://git.mean.io/orit/upload中管理的,但即使這個月也沒有更新... –

回答

25

我最近做了這樣的事情。我用angular-file-upload。您還需要node-multiparty爲您的端點解析表單數據。然後,您可以使用s3將文件上傳到s3。

這是我編輯的一些代碼。

角模板

<button> 
    Upload <input type="file" ng-file-select="onFileSelect($files)"> 
</button> 

角控制器

$scope.onFileSelect = function(image) { 
    $scope.uploadInProgress = true; 
    $scope.uploadProgress = 0; 

    if (angular.isArray(image)) { 
    image = image[0]; 
    } 

    $scope.upload = $upload.upload({ 
    url: '/api/v1/upload/image', 
    method: 'POST', 
    data: { 
     type: 'profile' 
    }, 
    file: image 
    }).progress(function(event) { 
    $scope.uploadProgress = Math.floor(event.loaded/event.total); 
    $scope.$apply(); 
    }).success(function(data, status, headers, config) { 
    AlertService.success('Photo uploaded!'); 
    }).error(function(err) { 
    $scope.uploadInProgress = false; 
    AlertService.error('Error uploading file: ' + err.message || err); 
    }); 
}; 

路線

var uuid = require('uuid'); // https://github.com/defunctzombie/node-uuid 
var multiparty = require('multiparty'); // https://github.com/andrewrk/node-multiparty 
var s3 = require('s3'); // https://github.com/andrewrk/node-s3-client 

var s3Client = s3.createClient({ 
    key: '<your_key>', 
    secret: '<your_secret>', 
    bucket: '<your_bucket>' 
}); 

module.exports = function(app) { 
    app.post('/api/v1/upload/image', function(req, res) { 
    var form = new multiparty.Form(); 
    form.parse(req, function(err, fields, files) { 
     var file = files.file[0]; 
     var contentType = file.headers['content-type']; 
     var extension = file.path.substring(file.path.lastIndexOf('.')); 
     var destPath = '/' + user.id + '/profile' + '/' + uuid.v4() + extension; 

     var headers = { 
     'x-amz-acl': 'public-read', 
     'Content-Length': file.size, 
     'Content-Type': contentType 
     }; 
     var uploader = s3Client.upload(file.path, destPath, headers); 

     uploader.on('error', function(err) { 
     //TODO handle this 
     }); 

     uploader.on('end', function(url) { 
     //TODO do something with the url 
     console.log('file opened:', url); 
     }); 
    }); 
    }); 
} 

我改變噸他從我的代碼中獲得,所以它可能不適用,但希望它有幫助!

+0

嗨,感謝您的回答!我終於設法使它工作了!現在只有一個問題,即在我提交表單之前上傳圖像,但我認爲我可以設法按預期工作。我也使用了'angular-file-upload',但是(愚蠢的我)沒有檢查Chrome的控制檯是否有錯誤,我錯過了一些parentesis,它不工作(當然!)。但我設法使它工作!但是,謝謝你的回答! – Cacos

+1

@Cacos,我很高興你的工作。請接受這樣的答案,以便Google找到答案可以更輕鬆地找到答案。 – kentcdodds

+1

另外,作爲提示。開發時你應該總是打開控制檯...沒有它,開發很困難。當你發現... :-) – kentcdodds

3

最近一個新軟件包被添加到了mean.io上的軟件包列表中。這是一種美麗!

只需運行:

$意味着安裝平均上傳

這將安裝包到節點文件夾,但您可以訪問你的包指令。

http://mean.io/#!/packages/53ccd40e56eac633a3eee335

在您的表單視圖,添加如下內容:

<div class="form-group"> 
     <label class="control-label">Images</label> 
     <mean-upload file-dest="'/packages/photos/'" upload-file-callback="uploadFileArticleCallback(file)"></mean-upload> 
     <br> 
     <ul class="list-group"> 
      <li ng-repeat="image in article.images" class="list-group-item"> 
       {{image.name}} 
       <span class="glyphicon glyphicon-remove-circle pull-right" ng-click="deletePhoto(image)"></span> 
      </li> 
     </ul> 
    </div> 

而在你的控制器:

$scope.uploadFileArticleCallback = function(file) { 
     if (file.type.indexOf('image') !== -1){ 
      $scope.article.images.push({ 
      'size': file.size, 
      'type': file.type, 
      'name': file.name, 
      'src': file.src 
      }); 
     } 
     else{ 
      $scope.article.files.push({ 
      'size': file.size, 
      'type': file.type, 
      'name': file.name, 
      'src': file.src 
      }); 
     } 
    }; 

    $scope.deletePhoto = function(photo) { 
     var index = $scope.article.images.indexOf(photo); 
     $scope.article.images.splice(index, 1); 
    } 

享受!

0

我知道這個帖子是舊的。我遇到了它,@kentcdodds有一個我非常喜歡的答案,但他使用的圖書館現在已經過時了,我無法讓它們工作。所以在一些研究之後,我想分享一個更新的類似解決方案。採用NG-上傳

HTML

<form > 
    <div style="margin-bottom: 15px;"> 
     <button type="file" name="file" id="file" ngf-select="uploadFiles($file, $invalidFiles)" accept="image/*" ngf-max-height="1000" ngf-max-size="1MB">Select File</button> 
    </div> 
</form> 

INCLUDE NG-上傳模塊

下載,引用文件,包括模塊

var app = angular.module('app', ['ngFileUpload']); 

這會給你訪問Upload服務。

控制器代碼

$scope.uploadFiles = function(file, errFiles) { 
    $scope.f = file; 
    $scope.errFile = errFiles && errFiles[0]; 
    if (file) { 
     file.upload = Upload.upload({ 
      url: 'you-api-endpoint', 
      data: {file: file} 
     }); 

     //put promise and event watchers here if wanted 
    } 
}; 

NODE API代碼

所有下面的代碼是在一個單獨的文件route這是在我的主server.js文件required

require('./app/app-routes.js')(app, _);

var fs = require('fs'); 
var uuid = require('uuid'); 
var s3 = require('s3fs'); // https://github.com/RiptideElements/s3fs 
var s3Impl = new s3('bucketname', { 
    accessKeyId: '<your access key id>', 
    secretAccessKey: '< your secret access key >' 
}); 

var multiparty = require('connect-multiparty'); 
var multipartyMiddleware = multiparty(); 

module.exports = function(app, _) { 
    app.use(multipartyMiddleware); 


    app.post('/your-api-endpoint',function(req, res){ 

    var file = req.files.file; // multiparty is what allows the file to to be accessed in the req 
    var stream = fs.createReadStream(file.path); 
    var extension = file.path.substring(file.path.lastIndexOf('.')); 
    var destPath = '/' + req.user._id + '/avatar/' + uuid.v4() + extension; 
    var base = 'https://you-bucket-url'; 
    return s3Impl.writeFile(destPath, stream, {ContentType: file.type}).then(function(one){ 
     fs.unlink(file.path); 
     res.send(base + destPath); 
    }); 
}); 

所有我試圖做的是上傳頭像獨特的用戶。希望這可以幫助!!

相關問題