pjax 처리로 파일 업로드

8924 단어 jquery-pjax

묘사

PJAX를 최근에 사용하고 있습니다.비록 나는 그것의 작업 방식에 대해 매우 만족하지만, 내 플랫폼의 업로드 기능은 현재 이미 효력을 잃었다.
다음은 내 애플리케이션의 작동 방식입니다.
- jQuery File Upload으로 여러 파일 업로드 처리
- 내 백엔드는 Rails+Carrierwave
- 파일이 업로드되고 있어도 페이지 사이를 탐색할 수 있었습니다.
- PJAX는 각 요청에 새 DOM을 로드하므로 사용자가 파일을 업로드하지 못하도록 $(window).on('beforeunload', function() { });을 호출합니다.
다음은 제가 이루고 싶은 목표입니다.
- 파일 업로드가 진행 중이라도 사용자는 플랫폼에서 사방으로 이동할 수 있어야 한다(이전에 내 해커 솔루션을 사용했다)pjax:end을 사용하여 원하는 JS 함수를 로드합니다.
$(document).on('pjax:end', function(event) {
    console.log('Force Load');
    function1();
    function2();
});
다음은 jQuery 파일이 업로드한 JS입니다.
// Code for managing the entire uploads and progress bars - QC - OK
    var count = 0;
    var removeUploadStatusBoxOnCompletion = function() {
        if (count == 0) {
            $('.upload').hide();
            $('.external-drop-indicator').hide();
            $('#inline-upload-status').hide();
            $('.upload-status-box').hide();
        }
    };
    // Initialize the jQuery File Upload plugin - QC - OK
    $('#fileupload').fileupload({
        dataType: "script",
        sequentialUploads: true,
        // This function is called when a file is added to the queue;
        // either via the browse button, or via drag/drop:
        add: function(e, data) {
            data.context = $(tmpl("template-upload", data.files[
                    0]))
            data.context.addClass('working');
            //$('.upload-status-box').addClass('working');
            $('#Upload-Bar').append(data.context);
            $('.upload-status-box').show();
            // Listen for clicks on the cancel button
            data.context.find('span.cancel-upload').click(
                function() {
                    jqXHR.abort();
                    data.context.fadeOut(function() {
                        data.context.remove();
                    });
                    count = count - 1;
                    removeUploadStatusBoxOnCompletion();
                });
            var jqXHR = data.submit();
            count = count + 1;
        },
        progress: function(e, data) {
            if (data.context) {
                $('.upload-status-box').show();
                progress = parseInt((data.loaded / data.total) *
                    100);
                var uploadMeta = parseInt(data.loaded / 1000000) +
                    "/" + parseInt(data.total / 1000000) +
                    " MB - " + progress + "%";
                data.context.find('.progress-bar').css('width',
                    progress + '%');
                data.context.find('.status').text(uploadMeta);
            }
        },
        done: function(e, data) {
            console.log(
                'Your files have been uploaded successfully!'
            );
            // alert('Your files have been uploaded successfully! Depending on the file size, you might have to wait for a while before performing any actions.');
            count = count - 1;
            data.context.removeClass('working');
            data.context.find('button.cancel-upload').hide();
            removeUploadStatusBoxOnCompletion();
        }
    });
    // Alert user when he or she is moving away from the page - QC - OK
    $(window).on('beforeunload', function() {
        if ($('div.working').length != 0) {
            return 'Your files are still being uploaded. Moving away from this page might cancel the uploads!';
        }
    });
만약 누군가가 나를 도와 이 일을 해결할 수 있다면 정말 좋겠다!미리 고마워요.

토론 #1

Earlier, I was able to navigate between pages, even when the file is being uploaded


어떤 솔루션을 사용하여 페이지가 실제로 새로 고쳐지지 않고 페이지 사이를 탐색하고 업로드를 취소했습니까?

Since PJAX is loading a new DOM on every request, the $(window).on('beforeunload', function() { }) is being called, which is preventing the user to upload the files


이상하게 들린다.비록 pjax가 DOM에 삽입하기 위해 새로운 페이지 내용을 불러오고 있지만, 사실상 페이지를 새로 고침한 적이 없습니다. (이것이 바로 pjax의 모든 의미입니다.) 따라서 pjax의 일반적인 내비게이션 기간에 onbeforeunload을 영원히 호출하지 않습니다. 왜냐하면 페이지가 진정으로 새로 고침되지 않기 때문입니다.
그러나, 어떤 경우, pjax는 페이지에 하드코어로 다시 불러옵니다. 예를 들어, 서버에서 온전한 <html>... 응답을 받았을 때, 특정한 fragment: "#selector"을 추출하거나, 서버에서 빈 응답을 받았을 때.
이렇게 상세하게 소개해 주셔서 감사합니다. 그러나 당신의 문제를 더욱 잘 이해하기 위해서, 저는 pjax가 당신의 사이트에서 내비게이션을 할 때 어떤 일이 발생하고, 업로드에 어떻게 영향을 미칠지 상세하게 설명해 주셔야 합니다.

토론 #2

헤헤@mislav 감사합니다.

What solution did you use to navigate between pages without the page actually refreshing (and canceling the upload)?

:remote => true이 있었고, 컨트롤러는 JS 응답으로 응답했고, 이 응답은div를partial로 대체했다.이런 방식을 통해 DOM은 불러오는 데 사용되지만, 그 다음에 나는 aaxComplete () 방법에 필요한 함수를 불러왔다.나는 이것이 틀렸다는 것을 깨달았다.

However, in some cases pjax will hard-reload the page— such as when it receives a full ... response from the server but it's not configured to extract any particular fragment: "#selector" from it, or when it receives an empty response from the server.


그러면 :remote => true에 링크를 추가하고 컨트롤러에서 HTML로 응답하면 PJAX가 정상적으로 작동할 수 있다는 뜻입니까?아니면 제가 JS를 돌려줘야 하나요?
필요한 경우 추가 정보 +1:

토론 #셋

, :remote => true과 pjax를 동시에 사용하고 싶지 않으실 겁니다.그것들은 서로 다른 일을 하고 있으니 조합해서 사용해서는 안 된다.

I used to have :remote => true for which the controller replies back with a JS response that replaces a div with a partial.


이것은 듣기에는 좋지만, 이것은 브라우저 URL이 업데이트되지 않았고, 역사상 브라우저의 후퇴/전진 내비게이션을 사용한 적이 없다는 것을 의미한다.만약 당신이 이 물건들을 원한다면, pjax는 절대로 당신의 선택입니다.그러나 예상한 바와 같이, JS를 pjax 요청에 대한 응답으로 사용하지 않고 HTML 세션을 사용해야 합니다."pjax 용기"요소에 삽입할 HTML 부분만 보여 주십시오. 예를 들어 ID가 #main인 요소입니다.
컨트롤러 작업의 예:
def index
  respond_to do |format|
    format.html do
      render :layout => !pjax?
    end
  end
end

def pjax?
  request.headers["X-PJAX"]
end
현재, index 동작은 모든 pjax 요청에 레이아웃이 없는 HTML을 제공합니다.
또는, 백엔드에서 pjax 요청에 응답하는 방식을 바꾸고 모든 요청에 완전한 HTML (레이아웃) 을 계속 보여주지 않으려면, 백엔드에서 pjax를 설정해서 HTML의 한 부분만 추출할 수 있습니다.(ajax 요청에 대한 JS 서비스를 제공하지 않도록 서버를 설정해야 합니다.)다음과 같이 구성합니다.
$(document).pjax('a', '#main', { fragment: "#main" })
현재, pjax는 받은 서버 응답에서 #main 요소를 찾고 그 내용을 추출하여 DOM의 현재 #main 용기에 삽입하기를 희망합니다.

토론 #4

자세한 답변 감사합니다 @mislav.나는 나의 코드로 당신의 건의를 신속하게 검사한 후에 다시 당신에게 회답할 것입니다.:)

토론 #5

@mislav: 도와 주셔서 감사합니다.너의 위의 대답은 내가 PJAX를 Rails와 함께 일하게 하는 몇 가지 문제를 해결하는 데 도움을 주었다.근데 나 지금 새로운 문제 있어.다음과 같이 역사 PushState ID를 URL에 추가합니다. http://localhost:3000/myfolders/1?_=1428680562715 또는 이와 유사한 내용입니다.
screen shot 2015-04-10 at 9 39 19 pm
제출된 양식은 URL 필드에 있는 매개 변수를 인쇄한 다음 제출하여 전송된 데이터를 명확하게 드러냅니다.또 다른 문제는 사용자가 cmd+r으로 페이지를 갱신하거나 하드로 갱신할 때마다 DOM이 불러오지 않는다는 것이다.URL에 첨부된 매개변수 때문일 수 있습니다.
더 많은 정보를 드리겠습니다.다음은 제 JS의 모습입니다.
// app/assets/javascript/application.js
$(document).pjax('a[data-pjax]', '[data-pjax-container]', { fragment: '[data-pjax-container]' });
다음은 <div data-pjax-container>을 교체하기 위해 PJAX를 트리거하는 방법입니다.
# index.html.erb
<%= link_to myfolder.realname, myfolder, :data => {pjax: ''} %>
앞서 언급한 바와 같이 저는 <div data-pjax-container>의 내용만 바꾸려고 노력하고 있습니다. 이 부분은 매우 완벽하게 작동하고 있습니다.문제는 pjax-container 이외의 파일 업로드표가 있다는 것이다.이런 상황에서 모든 것이 정상적으로 작동해야 하지만 PJAX 내비게이션을 사용할 때마다 beforeunload:
    $(window).on('beforeunload', function() {
        if ($('div.working').length != 0) {
            return 'Your files are still being uploaded. Moving away from this page might cancel the uploads!';
        }
    });
벌써 일주일이 되었는데, 우리는 단지 이틀의 시간만 생산할 수 있다.이것은 유일하게 나를 두려워하게 하는 일이다.벌써 일주일이 되었는데, 우리는 단지 이틀의 시간만 생산할 수 있다.이것은 유일하게 나를 두려워하게 하는 일이다.

좋은 웹페이지 즐겨찾기