2015-01-19 15 views
5

Ich verwende MEAN.JS (https://github.com/meanjs/mean) und angular-Datei-Upload (https://github.com/danialfarid/angular-file-upload).Hinzufügen eines Bildes zum MEAN.JS-Beispiel mit Angular-Datei-Upload

Das von MEAN.JS bereitgestellte "Article" -Beispiel enthält zwei Felder namens "title" und "content". Ich möchte das ändern und ein "Bild" -Feld hinzufügen, das es einem Benutzer ermöglicht, ein Bild hochzuladen.

Ich verstehe, dass ich 3 Dateien in MEAN.JS ändern müssen:

~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 

jedoch kann ich sie nicht erfolgreich ändern.

+0

, welche Änderungen Sie haben versucht, so weit zu diesen Dateien zu machen? Obwohl es gut ist, dass du sie identifiziert hast, gibt es nicht viel zu tun, wenn wir nicht wissen, was du versucht hast. –

Antwort

7

Meine Lösung verwendet angular-file-upload auf dem Client und verwendet connect-multiparty die Datei-Upload zu handhaben .

Die Bilder werden direkt in der Datenbank gespeichert, was ihre Größe begrenzt. Ich habe den erforderlichen Code nicht zur Überprüfung der Bildgröße hinzugefügt.

einrichten

bower install ng-file-upload --save 
bower install ng-file-upload-shim --save 

npm i connect-multiparty 
npm update 

all.js hinzufügen Winkel-Datei-Upload-Skripten

  ... 
      '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 Inject Winkel-Datei-Upload-Abhängigkeit

... 
var applicationModuleVendorDependencies = ['ngResource', 'ngAnimate', 'ui.router', 'ui.bootstrap', 'ui.utils', 'angularFileUpload']; 
... 

article.client.controller.js Verwenden Winkel-Datei-Upload-Abhängigkeit

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); 
      } 
     } 
    }; 
} 

create-article.client.view.html aktualisieren Sie die create view Dateiauswahl zu handhaben und

<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> 

view-article.client.view.html Update Listenansicht Bild hochladen

<img ng-src="data:image/jpeg;base64,{{article.image}}" id="photo-id" width="200" height="200"/> 

list-Artikel aufzunehmen. client.view.html Ansicht aktualisieren, um die Bilder zu enthalten

<img ng-src="data:image/jpeg;base64,{{article.image}}" id="photo-id" width="40" height="40"/> 

article.server.model.js Bild hinzufügen, um Datenbankmodell

... 
image: { 
    type: String, 
    default: '' 
}, 
... 

article.server.routes.js neue Route hinzufügen für den Upload Verwendung connect-Mehr

... 
multiparty = require('connect-multiparty'), 
multipartyMiddleware = multiparty(), 
... 
app.route('/articleupload') 
    .post(users.requiresLogin, multipartyMiddleware, articles.createWithUpload); 
... 

article.server.controller.js Handle neue Route für den Upload erfordern 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); 
    } 
    }); 
}); 
}; 
... 
+0

Ich bin nicht in der Lage, dies zu arbeiten, haben Sie eine Lösung, die die Datei auf dem Server statt der Datenbank speichert? –

+0

Was schief geht, Fehlermeldungen und Code und ich kann Ihnen helfen. –

+0

siehe meine Lösung unter @John Purnell –

1

Meine Arbeitslösung in MEAN.js

Server-Modell:

image:{ 
    type: String, 
    default: '' 
}, 

Server-Controller:

var item = new Item(JSON.parse(req.body.item)); 
item.user = req.user; 
if(req.files.file) 
    item.image=req.files.file.name; 
else 
    item.image='default.jpg'; 

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

Server Strecke: (erfordert multer: "npm multer --save installieren")

var multer = require('multer'); 
app.use(multer({ dest: './public/uploads/'})); 

Frontend Winkelregler:

$scope.image=''; 

    $scope.uploadImage = function(e){ 
     console.log(e.target.files[0]); 
     $scope.image=e.target.files[0]; 

    }; 



    // Create new Item 
    $scope.create = function() { 
     // Create new Item object 
     var item = new Items ({ 
      name: this.name, 
      bought: this.bought, 
      number: this.number, 
      description: this.description, 
      warranty: this.warranty, 
      notes: this.notes 


     }); 

     ItemsService.saveItem(item,$scope.image); 

    }; 

Dienst, senden ist die Anfrage:

.factory('ItemsService', ['$http','$rootScope', function($http, $rootScope) 
{ 
    var service={}; 

    service.saveItem = function(item, image) 
    { 

     var fd = new FormData(); 
     fd.append('file', image); 
     fd.append('item', JSON.stringify(item)); 
     $http.post('items/', fd, { 
      transformRequest: angular.identity, 
      headers: {'Content-Type': undefined} 
     }) 
     .success(function(){ 
      console.log('success add new item'); 
     }) 
     .error(function(e){ 
      console.log('error add new item', e); 
     }); 


    }; 

    return service; 

} 

]); 

HTML-Ansicht:

  <div class="form-group"> 
       <label class="control-label" for="name">Image</label> 
       <div class="controls"> 
        <input type="file" data-ng-model="image" id="image" my-file-upload="uploadImage" required> 
        {{selectedFile.name}} 
       </div> 
      </div> 
+0

Hallo, ich habe versucht, Ihre Lösung zu implementieren, aber ich bekomme nur einen 'ItemsService ist nicht definiert' Fehler in meinem Modul-Controller. Weißt du, was ich falsch mache? –

+0

Wenn Sie es nicht bereits gelöst haben, geben Sie hier einen Code – Mike

+0

Ich füge die Fabrik zu meinem Client-Service auf verschiedene Arten, aber ich bekomme 'ItemsService ist nicht definiert: public \ modules \ testcruds \ controllers \ testcruds.client.controller. ItemsService.saveItem (testcrud, $ scope.image); 'ItemsService' ist nicht definiert. –

1

@John Prunell Vielen Dank für diesen, habe ich es endlich aus (hatte mich mehr als eine Woche, aber ich bin jetzt viel bequemer mit dem Stapel) Ich habe gegabelt es um es zu bekommen, die Datei zu laden in einen Ordner:

'exports.createWithUpload =  function(req, res) { 

var form = new multiparty.Form(); 
form.parse(req, function(err, fields, files) { 

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; 
var tmpPath = file.path; 
var extIndex = tmpPath.lastIndexOf('.'); 
var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex); 
var fileName = uuid.v4() + extension; 
var destPath = './uploads/' + fileName; 

article.image = fileName; 

var is = fs.createReadStream(tmpPath); 
var os = fs.createWriteStream(destPath); 

if(is.pipe(os)) { 
    fs.unlink(tmpPath, function (err) { //To unlink the file from temp path after copy 
     if (err) { 
      console.log(err); 
     } 
    }); 
    article.save(function(err) { 
    if (err) { 
     return res.status(400).send({ 
      message: errorHandler.getErrorMessage(err) 
     }); 
    } else { 
     res.jsonp(article); 
    } 
}); 
}else 
    return res.json('File not uploaded'); 
}); 

}; 

Was ich jetzt tun möchte, ist Ihre Lösung Gabel Hochladen mehrerer Bilder in der gleichen Art und Weise zu ermöglichen, wenn Sie nicht nur die Einsicht in haben, wie dies zu tun, das wäre großartig, ich will lass dich wissen, wie es mir geht.

2

Danke Charlie Tupman für diese letzte Lösung, die sehr gut funktioniert.

ich fügen Sie einfach die Abhängigkeiten:

... 
multiparty = require('multiparty'), 
uuid = require('uuid'), 
... 

vor der Exporte Funktion und geändert zwei Linien um das Verhalten zu verbessern:

... 
var destPath = './public/uploads/' + fileName; 

article.image = '/uploads/' + fileName; 
... 

die Entschlossenheit in:

exports.createWithUpload = function(req, res) { 

    var form = new multiparty.Form(); 
    form.parse(req, function(err, fields, files) { 

     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; 
     var tmpPath = file.path; 
     var extIndex = tmpPath.lastIndexOf('.'); 
     var extension = (extIndex < 0) ? '' : tmpPath.substr(extIndex); 
     var fileName = uuid.v4() + extension; 
     var destPath = './public/uploads/' + fileName; 

     article.image = '/uploads/' + fileName; 

     var is = fs.createReadStream(tmpPath); 
     var os = fs.createWriteStream(destPath); 

     if(is.pipe(os)) { 
      fs.unlink(tmpPath, function (err) { //To unlink the file from temp path after copy 
       if (err) { 
        console.log(err); 
       } 
      }); 
      article.save(function(err) { 
       if (err) { 
        return res.status(400).send({ 
         message: errorHandler.getErrorMessage(err) 
        }); 
       } else { 
        res.jsonp(article); 
       } 
      }); 
     } else 
      return res.json('File not uploaded'); 
    }); 

}; 
Verwandte Themen