2012-11-07 18 views
5

hey m utilizza mvc3 con knockout e tenta di utilizzare il binding a eliminazione diretta per caricare e salvare l'immagine caricata nel database. Sono in grado di sfogliare e ottenere l'immagine, ma non come ottenere come salvare quell'immagine. mio punto di vista l'HTML è:come caricare l'immagine e salvarla nel database usando knockout js?

<div data-bind="foreach: { data: images, beforeRemove: beforeRemoveSlot }"> 
     <div> 
      <input type="file" accept="image/*" data-bind="file: imageFile, fileObjectURL: imageObjectURL, fileBinaryData: imageBinary"/> 
      <div data-bind="if: imageObjectURL"> 
       <img class="thumb" data-bind="attr: { src: imageObjectURL }"/> 
      </div> 
      <div>Size: <span data-bind="text: fileSize"></span>&nbsp;bytes</div> 
     </div> 
    </div> 
     <input type="submit" value="Upload Picture" data-bind="click: upload" /> 

mio punto di vista il modello è:

var windowURL = window.URL || window.webkitURL; 

ko.bindingHandlers.file = { 
    init: function (element, valueAccessor) { 
     $(element).change(function() { 
      var file = this.files[0]; 
      if (ko.isObservable(valueAccessor())) { 
       valueAccessor()(file); 
      } 
     }); 
    }, 

    update: function (element, valueAccessor, allBindingsAccessor) { 
     var file = ko.utils.unwrapObservable(valueAccessor()); 
     var bindings = allBindingsAccessor(); 

     if (bindings.fileObjectURL && ko.isObservable(bindings.fileObjectURL)) { 
      var oldUrl = bindings.fileObjectURL(); 
      if (oldUrl) { 
       windowURL.revokeObjectURL(oldUrl); 
      } 
      bindings.fileObjectURL(file && windowURL.createObjectURL(file)); 
     } 

     if (bindings.fileBinaryData && ko.isObservable(bindings.fileBinaryData)) { 
      if (!file) { 
       bindings.fileBinaryData(null); 
      } else { 
       var reader = new FileReader(); 
       reader.onload = function (e) { 
        bindings.fileBinaryData(e.target.result); 
       }; 
       reader.readAsArrayBuffer(file); 
      } 
     } 
    } 
}; 

var imageUploadModel = function() { 
    var self = {}; 

    var slotModel = function() { 
     var that = {}; 

     that.imageFile = ko.observable(); 
     that.imageObjectURL = ko.observable(); 
     that.imageBinary = ko.observable(); 

     that.fileSize = ko.computed(function() { 
      var file = this.imageFile(); 
      return file ? file.size : 0; 
     }, that); 

     that.firstBytes = ko.computed(function() { 
      if (that.imageBinary()) { 
       var buf = new Uint8Array(that.imageBinary()); 
       var bytes = []; 
       for (var i = 0; i < Math.min(10, buf.length); ++i) { 
        bytes.push(buf[i]); 
       } 
       return '[' + bytes.join(', ') + ']'; 
      } else { 
       return ''; 
      } 
     }, that); 

     return that; 
    }; 

    self.beforeRemoveSlot = function (element, index, data) { 
     if (data.imageObjectURL()) { 
      windowURL.revokeObjectURL(data.imageObjectURL()); 
     } 
     $(element).remove(); 
    }; 

    self.images = ko.observableArray([slotModel()]); 

    self.addSlot = function() { 
     self.images.push(slotModel()); 
    }; 

    self.removeSlot = function (data) { 
     self.images.remove(data); 
    }; 

    return self; 
}(); 

imageUploadModel.upload = function() { 

} 

$(document).ready(function() { 
    ko.applyBindings(imageUploadModel); 
}); 

qualcuno mi può suggerire come posso salvare l'immagine sul pulsante di caricamento clicca ?????

risposta

16

Ecco un esempio di singoli arrivi Clicca sull'immagine via knockout ho strofinato insieme

html ->

<input type="file" data-bind="value: fileName, fileUpload: fileName, url: url"> 
<script src="{{ STATIC_URL }}html5knockoutImagePreview.js"></script>​ 

js ->

ko.bindingHandlers.fileUpload = { 

update: function(element, valueAccessor, allBindingsAccessor){ 
     var value = ko.utils.unwrapObservable(valueAccessor()) 
     if(element.files.length && value){ 
     var file = element.files[0]; 
     var url = allBindingsAccessor().url 

     xhr = new XMLHttpRequest(); 
     xhr.open("post", url, true); 
     xhr.setRequestHeader("Content-Type", "image/jpeg"); 
     xhr.setRequestHeader("X-File-Name", file.name); 
     xhr.setRequestHeader("X-File-Size", file.size); 
     xhr.setRequestHeader("X-File-Type", file.type); 
     console.log("sending") 
     // Send the file (doh) 
     xhr.send(file); 
     } 
    } 
} 


function MainPageViewModal(){ 
    this.fileName = ko.observable() 
    this.url = "http://127.0.0.1:8000/upload" 
} 

var mainPageViewModal = new MainPageViewModal() 

ko.applyBindings(mainPageViewModal); 

fiddle

I' Non sono sicuro al 100% di tutti i tuoi requisiti, questo è per jpegs, è necessario modificare il tipo di intestazione di contenuti per altri tipi ecc

Modifica

Come si sta continuando ad avere problemi, ecco qualche codice che ho scritto da allora che potrebbe aiutare. Lo fa utilizzare jQuery però ...

ko attacchi ->

ko.bindingHandlers.filePreview = { 
    update: function(element, valueAccessor, allBindingsAccessor){ 
     var allBindings = allBindingsAccessor() 
     if(!!FileReader && valueAccessor() && element.files.length){ 
     var reader = new FileReader(); 
     reader.onload = function(event){ 
      var dataUri = event.target.result 
      allBindings.imagePreview(dataUri) 
     } 
     reader.onerror = function(e) { 
      console.log("error", stuff) 
     } 
     reader.readAsDataURL(element.files[0]) 
    } 
    } 
} 

modelPageView ->

, uploadPreview: function(files){ 
     var self = this 
     self.loadingPreview(true) 
     file = files[0] 
     if(file.size > 20000000){ 
      alert("that image is a bit too big for us, got anything smaller?") 
     } 
     console.log("file size " + file.size) 
     var formData = new FormData(); 
     formData.append("img", file) 
     $.ajax({ 
      url: "/YOUR_UPLOAD_URL", 
      type: 'POST', 
      data: formData, 
      cache: false, 
      contentType: false, 
      processData: false 
     }).done(function(data){ 
     if(data === "error"){ 
      alert("somethign wrong happened, please refresh the page") 
      return 
     } 
     self.imgUrl(data.img_url) 
     self.imgId(data.img_id) 
     }).fail(function(){ 
     self.loadingPreview(false) 
     }) 
} 

html ->

<input type="file" accept="image/*" name="img" data-bind="value: img, fileAdded: img, previewFunc: function(files){ $data.uploadPreview(files) }" /> 
  • I vantaggi di questo metodo è un sacco di quadri come i dati del modulo anziché solo i dati del tipo di contenuto dell'immagine meglio.
  • Personalmente penso che l'interazione lato server debba essere guidata dal modal backend , ecco perché il codice è lì invece che nel gestore di binding .
  • Hai anche la magia dell'oggetto jQuery ajax se ne hai bisogno.

Scusate per il ritardo nella risposta, avrò un picco in un paio di giorni, quindi fatemi sapere se avete ancora problemi.

Buona fortuna!

+0

declinazione di responsabilità -> Questo codice non funziona in ie 9 o inferiore in quanto non supportano l'hpiml file api (ho pensato che lo sapevi come era il metodo che stavi usando ma per chiunque altro leggendo questo ...) – Fred

+1

hey fred, thnkx per la risposta, ma continua a sfogliare l'immagine, non riesco ancora a salvare quell'immagine sfogliata nella mia cartella. – Parasignals

+1

Sto usando questo binding per ko, e ho impostato l'url: "Action/Controller", ma cosa ho bisogno di impostare i parametri come per il metodo Action? Il parametro HttpPostedFileBase viene sempre visualizzato come null. – jmogera

Problemi correlati