5

嘿 m 使用带有敲除的 mvc3 并尝试使用敲除绑定来上传上传的图像并将其保存在数据库中。我能够浏览并获取图像,但无法获取如何保存该图像。我的 html 视图是:

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

我的视图模型是:

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

任何人都可以建议我如何在上传按钮单击时保存图像??????

4

1 回答 1

16

这是通过淘汰赛上传单击图像的示例,我已经一起擦洗了

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

小提琴

我不能 100% 确定您的所有要求,这是针对 jpeg 的,您需要调整其他类型的内容类型标头等。

编辑

当您继续遇到问题时,这里有一些我从那时起编写的代码可能会有所帮助。它确实使用jquery...

ko 绑定 ->

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

模型页面视图->

, 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) }" />
  • 这种方法的优点是很多框架喜欢表单数据而不是仅仅图像内容类型的数据更好。
  • 我个人认为服务器端交互应该由后端模式驱动,这就是为什么代码在那里而不是绑定处理程序中的原因。
  • 如果需要,您还可以获得 jquery ajax 对象的魔力。

抱歉回复晚了,我会在几天后达到高峰,所以如果您仍有问题,请告诉我。

祝你好运!

于 2012-11-11T01:53:31.620 回答