2013-08-07 3 views
2

Я использую подключаемый модуль jQuery для загрузки файлов (https://github.com/blueimp/jQuery-File-Upload) с приложением MVC4.Событие jQuery становится неприкрепленным при загрузке частичного представления

Функциональность загрузки файлов (загрузка и таблица загруженных файлов) содержится в частичном представлении.

Таким образом, у меня есть несколько видов, которые содержат частичный вид загрузки файлов. Когда файл загружается, активируется действие «Сохранить» контроллера вложения. Это обрабатывает сохранение файла, а затем извлекает обновленный список файлов для этой конкретной области сайта. Затем представление возвращается в файл jQuery fileupload, а затем вставляет Html в div на родительской странице (#_attachments).

Все это прекрасно работает в том, что все делает правильно. Проблема, с которой я сталкиваюсь, заключается в том, что после загрузки файла и частичного просмотра перезагружается через jQuery, файловая загрузка больше не работает.

Похоже, что это может быть связано с тем, что событие больше не привязано к элементу управления #fileUpload. Я попытался использовать метод «on», но это тоже не работает.

Частичный вид сценария

$(function() { 
     $('#fileUpload').fileupload({ 
      url: "/Attachment/Save", 
      done: function (e, data) { 
       // "data.result" will contain the response data 
       $("#fileUploadProgress").hide(); 
       $("#_attachments").html(data.result); 
      }, 
      progressall: function (e, data) { 
       var progress = parseInt(data.loaded/data.total * 100, 10); 
       $("#fileUploadProgress").show(); 
       $("#fileUploadProgress .bar").css("width", progress + "%"); 
      } 
     }); 
    }); 

Controller/Action

[HttpPost] 
     public ActionResult Save() 
     { 

      // Get a reference to the file that our jQuery sent. Even with multiple files, they will all be their own request and be the 0 index 
      HttpPostedFileBase file = HttpContext.Request.Files[0]; 

      int ncpId = Convert.ToInt32(Request.Form["ncpId"]); 
      int stage = Convert.ToInt32(Request.Form["stage"]); 

      ncpRepository.SaveAttachmentToDb(file, CurrentUser.UserId, ncpId, stage); 

      //return the partial view to refresh the list of files 
      var attachments = ncpRepository.GetAttachmentsForRecord(ncpId); 
      var attachmentsViewModel = AutoMapper.Mapper.Map<IQueryable<Attachment>, List<AttachmentViewModel>>(attachments); 

      ViewData["Stage"] = stage; 

      return PartialView("_StageAttachments", attachmentsViewModel); 
     } 
+0

Просто догадаться, но выполняете ли вы частичный скрипт каждый раз, когда часть загружается? Мне не нужен «on» binder, вам просто нужно инициализировать плагин fileupload каждый раз, я полагаю. – Moeri

ответ

1

Оказывается, что это может быть связано с событием больше не прикрепленным контролю #fileUpload ,

Да, это то, на что похоже. Теперь у вас есть несколько проблем с вашим кодом. Первая проблема заключается в том, что вы упомянули, что этот код javascript находится внутри частичного представления. Но частичные представления не должны содержать никаких скриптов. Javascripts относятся к отдельным файлам. Также, похоже, вы использовали селектор $('#fileUpload'), который является селектором идентификаторов. Тогда вы сказали, что у вас есть много таких частичных представлений. Таким образом, вы потенциально можете сломать DOM, потому что у вас может быть только один элемент с указанным идентификатором во всем HTML.

Итак, давайте начнем фиксируя эту ситуацию, перемещая этот скрипт в отдельный файл (ссылка из основного зрения один раз) и который будет повторно подключить управление FileUpload к новым элементам в DOM:

var attachFileUploads = function() { 
    $('.fileUpload').fileupload({ 
     url: "/Attachment/Save", // TODO: Never hardcode an url like that, read it from an HTML 5 data-* attribute on the corresponding file input such as data-url="@Url.Action("Save", "Attachment")" 
     done: function (e, data) { 
      $("#fileUploadProgress").hide(); 
      $("#_attachments").html(data.result); 
      attachFileUploads(); // <!-- reattach the fileupload plugin 
     }, 
     progressall: function (e, data) { 
      var progress = parseInt(data.loaded/data.total * 100, 10); 
      $("#fileUploadProgress").show(); 
      $("#fileUploadProgress .bar").css("width", progress + "%"); 
     } 
    }); 
}; 

$(attachFileUploads); 

В этом Например, я использовал селектор классов $('.fileUpload'), который предполагает, что у вас может быть более одного ввода файла. Убедитесь, что вы присвоили ему этот класс и что вы избавились от id, который должен быть уникальным, как упоминалось ранее.

+0

Спасибо Дарин. Элемент управления загрузкой файлов находится только в частичном представлении, поэтому он объявляется только один раз на странице, поэтому использование этого идентификатора в этом случае прекрасное. Я обновлю свой код, чтобы отразить ваш подход и посмотреть, как я нахожусь. – sparkymark75

+0

Отлично, отлично работает, спасибо. Я также удалил жесткий код и заменил его значением URL-адреса. – sparkymark75