2013-06-27 13 views
5

ho scritto questo knockout per il file jsKnockout JS: Caricamento file evento

upload

Questo codice attiva l'evento caricati quando l'utente seleziona un file nel controllo di caricamento

Upload.html

$(function() { 
     var viewModel = { 
      filename: ko.observable(""), 
     }; 

     ko.applyBindings(viewModel); 
    }); 

<form> 
<input id="upload" name="upload" 
    data-bind="fileUpload: { property: 'filename', url: 'http://localhost/api/upload/PostFormData' }" 
    type="file" /> 

<button id="submitUpload">Upload</button> 
</form> 

FileUpload.js

ko.bindingHandlers.fileUpload = { 
init: function (element, valueAccessor) { 
    $(element).after('<div class="progress"><div class="bar"></div><div class="percent">0%</div></div><div class="progressError"></div>'); 
}, 
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 


    var options = ko.utils.unwrapObservable(valueAccessor()), 
     property = ko.utils.unwrapObservable(options.property), 
     url = ko.utils.unwrapObservable(options.url); 



    if (property && url) { 

     $(element).change(function() { 
      if (element.files.length) { 
       var $this = $(this), 
        fileName = $this.val(); 

       // this uses jquery.form.js plugin 
       $(element.form).ajaxSubmit({ 
        url: url, 
        type: "POST", 
        dataType: "text", 
        headers: { "Content-Disposition": "attachment; filename=" + fileName }, 
        beforeSubmit: function() { 
         $(".progress").show(); 
         $(".progressError").hide(); 
         $(".bar").width("0%") 
         $(".percent").html("0%"); 

        }, 
        uploadProgress: function(event, position, total, percentComplete) { 
         var percentVal = percentComplete + "%"; 
         $(".bar").width(percentVal) 
         $(".percent").html(percentVal); 

        }, 
        success: function(data) { 
         //$(".progress").hide(); 
         //$(".progressError").hide(); 
         // set viewModel property to filename 
         $("label[for='upload']").text(data); 

         bindingContext.$data[property](data); 
        }, 
        error: function(jqXHR, errorThrown) { 
         $(".progress").hide(); 
         $("div.progressError").html(jqXHR.responseText); 
        } 
       }); 
      } 
     }); 
    } 
} 

}

Ora, voglio spostare l'innesco di evento caricamento sul pulsante di invio

<button id="submitUpload">Upload</button> 

Come fare questo? In questo momento sono qui, ho solo spostato l'evento di caricamento all'interno dell'evento click del pulsante. Ma non funziona, e non chiama la richiesta Ajax all'API.

$('#submitUpload').click(function() { 

      if (element.files.length) { 

       var $this = $(element), 
        fileName = $this.val(); 
       //alert(element.form); 

       // this uses jquery.form.js plugin 
       $(element.form).ajaxSubmit({ 
        url: url, 
        type: "POST", 
        dataType: "text", 
        headers: { "Content-Disposition": "attachment; filename=" + fileName }, 
        beforeSubmit: function() { 
         $(".progress").show(); 
         $(".progressError").hide(); 
         $(".bar").width("0%") 
         $(".percent").html("0%"); 

        }, 
        uploadProgress: function(event, position, total, percentComplete) { 
         var percentVal = percentComplete + "%"; 
         $(".bar").width(percentVal) 
         $(".percent").html(percentVal); 

        }, 
        success: function(data) { 
         //$(".progress").hide(); 
         //$(".progressError").hide(); 
         // set viewModel property to filename 
         $("label[for='upload']").text(data); 

         bindingContext.$data[property](data); 
        }, 
        error: function(jqXHR, errorThrown) { 
         $(".progress").hide(); 
         $("div.progressError").html(jqXHR.responseText); 
        } 
       }); 
      } 
     }); 

risposta

0

elemento è sconosciuto al momento del clic. devi trovarlo sul modulo. Avviare la prima riga della funzione click con

element = $('#upload').get(0); 

e sostituire il tag pulsante con il seguente

<input type="button" id="submitUpload" value="Upload"></input> 

perché il tag tasto invia automaticamente il modulo.

3

Invece di passare solo il nome, URL al bindinghandler passare terzo parametro (fileBinaryData) dal ViewModel Object quindi leggere il file di contenuto nel metodo Update KO BindingHandler quindi aggiornare terzo metodo di aggiornamento osservabile (fileBinaryData) in.

Quindi è possibile utilizzare questi dati filebinary in voi ViewModel

così per l'evento click pulsante di collegamento e di accesso fileBinaryData osservabile che avrà il contenuto del file.

BindingHandler:

ko.bindingHandlers.FileUpload = { 
    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.fileBinaryData && ko.isObservable(bindings.fileBinaryData)) { 
      if (!file) { 

       bindings.fileBinaryData(null); 
      } else { 
       var reader = new window.FileReader(); 
       reader.onload = function (e) { 

        bindings.fileBinaryData(e.target.result); 
       }; 
       reader.readAsBinaryString(file); 
      } 
     } 
    } 
} 

HTML:

<input type="file" id="fileUpload" class="file_input_hidden" data-bind="FileUpload: spFile, fileObjectURL: spFileObjectURL, fileBinaryData: spFileBinary" /> 

ViewModel:

var viewModel = { 
     filename: ko.observable(""), 
     url: ko.observable(), 
     spFileBinary:ko.observable(), 
     //Write your CLICK EVENTS 
    }; 

Spero che questo aiuti :)

+1

Ciao, non riesco a far funzionare questo ... Ci sono delle versioni funzionanti su JSFiddle? Sto ottenendo l'elemento è errori non definiti. Immagino che potrei aver messo l'id sbagliato per qualche motivo. Grazie – Thony

Problemi correlati