我正在使用MEAN.JS(
https://github.com/meanjs/mean)和angular-file-upload(
https://github.com/danialfarid/angular-file-upload).
MEAN.JS提供的“Article”样本包含两个名为“title”和“content”的字段.我想修改它并添加一个“图片”字段,允许用户上传图片.
~myproject/app/models/article.server.model.js ~myproject/public/modules/articles/controllers/articles.client.controller.js ~myproject/public/modules/articles/views/create-article.client.view.html
但是,我无法成功修改它们.
我的解决方案在客户端上使用
angular-file-upload并使用
connect-multiparty来处理文件上载.
图像直接存储在数据库中,这限制了它们的大小.我没有包含检查图像大小所需的代码.
建立
bower install ng-file-upload --save bower install ng-file-upload-shim --save npm i connect-multiparty npm update
all.js
添加angular-file-upload脚本
... 'public/lib/ng-file-upload/FileAPI.min.js','public/lib/ng-file-upload/angular-file-upload-shim.min.js','public/lib/angular/angular.js','public/lib/ng-file-upload/angular-file-upload.min.js',...
config.js
注入angular-file-upload依赖项
... var applicationModuleVendorDependencies = ['ngResource','ngAnimate','ui.router','ui.bootstrap','ui.utils','angularFileUpload']; ...
article.client.controller.js
使用angular-file-upload依赖项
angular.module('articles').controller('ArticlesController',['$scope','$timeout','$upload','$stateParams','$location','Authentication','Articles',function($scope,$timeout,$upload,$stateParams,$location,Authentication,Articles) { $scope.fileReaderSupported = window.FileReader !== null; // Create new Article $scope.create = function(picFile) { console.log('create'); console.log(picFile); var article = new Articles({ title: this.title,content: this.content,image: null }); console.log(article); $upload.upload({ url: '/articleupload',method: 'POST',headers: {'Content-Type': 'multipart/form-data'},fields: {article: article},file: picFile,}).success(function (response,status) { $location.path('articles/' + response._id); $scope.title = ''; $scope.content = ''; }).error(function (err) { $scope.error = err.data.message; }); }; $scope.doTimeout = function(file) { console.log('do timeout'); $timeout( function() { var fileReader = new FileReader(); fileReader.readAsDataURL(file); console.log('read'); fileReader.onload = function(e) { $timeout(function() { file.dataUrl = e.target.result; console.log('set url'); }); }; }); }; $scope.generateThumb = function(file) { console.log('generate Thumb'); if (file) { console.log('not null'); console.log(file); if ($scope.fileReaderSupported && file.type.indexOf('image') > -1) { $scope.doTimeout(file); } } }; }
创建-article.client.view.html
更新创建视图以处理文件选择和上载
<section data-ng-controller="ArticlesController"> <div class="page-header"> <h1>New Article</h1> </div> <div class="col-md-12"> <form name="articleForm" class="form-horizontal" data-ng-submit="create(picFile)" novalidate> <fieldset> <div class="form-group" ng-class="{ 'has-error': articleForm.title.$dirty && articleForm.title.$invalid }"> <label class="control-label" for="title">Title</label> <div class="controls"> <input name="title" type="text" data-ng-model="title" id="title" class="form-control" placeholder="Title" required> </div> </div> <div class="form-group"> <label class="control-label" for="content">Content</label> <div class="controls"> <textarea name="content" data-ng-model="content" id="content" class="form-control" cols="30" rows="10" placeholder="Content"></textarea> </div> </div> <div class="form-group"> <label class="control-label" for="articleimage">Article Picture</label> <div class="controls"> <input id="articleimage" type="file" ng-file-select="" ng-model="picFile" name="file" accept="image/*" ng-file-change="generateThumb(picFile[0],$files)" required=""> <br/> <img ng-show="picFile[0].dataUrl != null" ng-src="{{picFile[0].dataUrl}}" class="img-thumbnail" height="50" width="100"> <span class="progress" ng-show="picFile[0].progress >= 0"> <div style="width:{{picFile[0].progress}}%" ng-bind="picFile[0].progress + '%'" class="ng-binding"></div> </span> <span ng-show="picFile[0].result">Upload Successful</span> </div> </div> <div class="form-group"> <input type="submit" class="btn btn-default" ng-disabled="!articleForm.$valid" ng-click="uploadPic(picFile)"> </div> <div data-ng-show="error" class="text-danger"> <strong data-ng-bind="error"></strong> </div> </fieldset> </form> </div> </section>
视图article.client.view.html
更新列表视图以包含图像
<img ng-src="data:image/jpeg;base64,{{article.image}}" id="photo-id" width="200" height="200"/>
列表articles.client.view.html
更新视图以包含imgae
<img ng-src="data:image/jpeg;base64,{{article.image}}" id="photo-id" width="40" height="40"/>
article.server.model.js
将图像添加到数据库模型
... image: { type: String,default: '' },...
article.server.routes.js
添加新上传路由使用connect-multiparty
... multiparty = require('connect-multiparty'),multipartyMiddleware = multiparty(),... app.route('/articleupload') .post(users.requiresLogin,multipartyMiddleware,articles.createWithUpload); ...
article.server.controller.js
处理上传新路线需要fs
... fs = require('fs'),... /** * Create a article with Upload */ exports.createWithUpload = function(req,res) { var file = req.files.file; console.log(file.name); console.log(file.type); console.log(file.path); console.log(req.body.article); var art = JSON.parse(req.body.article); var article = new Article(art); article.user = req.user; fs.readFile(file.path,function (err,original_data) { if (err) { return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); } // save image in db as base64 encoded - this limits the image size // to there should be size checks here and in client var base64Image = original_data.toString('base64'); fs.unlink(file.path,function (err) { if (err) { console.log('Failed to delete ' + file.path); } else{ console.log('successfully deleted ' + file.path); } }); article.image = base64Image; article.save(function(err) { if (err) { return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); } else { res.json(article); } }); }); }; ...