2012-11-07 12 views
5

hej m używając mvc3 z nokautem i próbując użyć wiązania knockout do wgrania i zapisania przesłanego obrazu w bazie danych. jestem w stanie przeglądać i uzyskiwać obraz, ale nie mam sposobu na zapisanie tego obrazu. mój widok HTML jest:jak wgrać obraz i zapisać go w bazie danych za pomocą nokautu?

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

moim zdaniem model jest:

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

może ktoś zasugerować mi jak mogę zapisać obraz na przycisk wysyłania kliknij ?????

Odpowiedz

16

oto przykład pojedynczych przesłane Kliknij obrazek, poprzez nokaut Mam usunięty wraz

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 nie jestem w 100% pewny wszystkich twoich wymagań, to jest dla jpegs, musisz poprawić treść nagłówka typu dla innych typów itp

Edit

jak jesteś nadal masz problemy, oto niektóre kod, który pisałem od tego czasu, że może pomóc. Czyni użyć jQuery chociaż ...

ko Wiązania ->

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) }" /> 
  • Zaletami tej metody jest wiele frameworków, takich jak dane formularzy zamiast lepszych danych typu zawartości obrazu.
  • Osobiście uważam, że interakcja po stronie serwera powinna być sterowana modulem zaplecza , dlatego właśnie kod jest tam, a nie w obsłudze wiążącej .
  • Otrzymujesz również magię obiektu ajax jquery, jeśli jest to potrzebne.

Przepraszamy za opóźnienie w odpowiedzi. Zajmę kilka dni, więc daj mi znać, jeśli nadal masz problemy.

Powodzenia!

+0

zrzeczenie się -> Ten kod nie działa w wersji 9 lub niższej, ponieważ nie obsługuje api pliku html5 (domyśliłem się, że wiesz o tym, ponieważ była to metoda, z której korzystałeś, ale dla kogokolwiek czytającego to ...) – Fred

+1

hej fred, thnkx za odpowiedź ur, ale nadal przeglądając obraz, nadal nie mogę zapisać tego przeglądanego obrazu w moim folderze. – Parasignals

+1

Używam tego powiązania dla ko, a ja ustawiam URL: "Action/Controller", ale czego potrzebuję ustawić parametr jak dla metody działania? Parametr HttpPostedFileBase zawsze przychodzi jako null. – jmogera

Powiązane problemy