2012-03-29 5 views
0

backbone.js를 사용하여 응용 프로그램을 개발 중입니다. & jquery. 나는 모델에서 코드를 다음 있습니다 :Backbone.js & jquery - show() 요소

runReport: function() { 
    this.set({generatingReport: true});  
    //long computation... 
    this.set({generatingReport: false});  
} 

과 (초기화 기능에서) 해당보기에서 다음 코드 :

... 
events { 
    "click #btn-run": "runReport" 
} 
... 
runReport: function() { 
    this.model.runReport(); 
} 
: 여기

... 
var that = this; 
... 

this.model.bind("change:generatingReport", function() {      
    if(that.model.get("generatingReport") === true) { 
     $("#report").empty().append("<h1>Generating report...</h1>").show(0); 
     console.log("begin"); 
    } else if(that.model.get("generatingReport") === false) { 
     $("#report").empty().append("<h1>Report generated</h1>").show(0); 
     console.log("end"); 
    } 
}); 

및 활동을 실행 뷰의 코드는

제 문제는 "Generatin report ..."메시지가 전혀 표시되지 않는다는 것입니다 (로그 메시지가 인쇄 됨). 보고서가 생성되면 "보고서 생성됨"이 나타납니다.

나는 다음과 같은 경우 (IF 지점에서 추가 경고 참조)
this.model.bind("change:generatingReport", function() {      
    if(that.model.get("generatingReport") === true) { 
     $("#report").empty().append("<h1>Generating report...</h1>").show(0); 
     console.log("begin"); 
     alert("stop!"); 
    } else if(that.model.get("generatingReport") === false) { 
     $("#report").empty().append("<h1>Report generated</h1>").show(0); 
     console.log("end"); 
    } 
}); 

다음 "보고서를 생성하는 것은 ..."표시됩니다. "long computation ..."부분에는 메시지를 숨길 수있는 숨기기 jquery 호출이 없습니다.

어떤 아이디어가 있습니까?

+0

BTW 긴 계산에 약 20 초가 걸리므로 "보고서 생성 중 ..."이 "보고서 생성 됨"으로 즉시 대체됩니다. –

+0

'# report'는 어디에 있습니까? 보기가 제어하는 ​​html의 일부입니까, 일부는'el'입니까? 또는 이미 존재하는 페이지의 다른 부분입니까? –

+0

네, 뷰 컨트롤의 부분입니다 –

답변

1

아마 여기서 일어나는 일은 브라우저가 UI를 업데이트 할 기회가 없다는 것입니다. 클릭 이벤트에 대한 이벤트 처리기에서 오랜 계산 시간이 모두 발생합니다. 아마도 브라우저 (아마도 "아마도"아마 여기서는 브라우저 스레딩 모델에서 전문가가 아니기 때문에 많은 말을 할 것입니다!)가 Javascript 코드에 click 이벤트를 전달한 다음 이벤트 핸들러가 UI를 업데이트/다시 그리기 전에 완료 될 때까지 기다립니다 . 이 경우 긴 프로세스가 끝날 때까지 컨트롤을 끝내지 않으므로 (끝내기 만하면 UI가 한 번만 다시 그려집니다) DOM의 #report 노드는 코드에 따라 내부적으로 변경되지만 프로세스가 끝날 때까지 화면에서 다시 그릴 수있는 기회는 없습니다. 이 최적인지는 모르겠지만,이 같은 뭔가 도움이 될 수 있습니다 : 난 그냥 50 밀리 초 동안 긴 처리를 연기가 밑줄의 지연() 함수를 사용하고

runReport: function() { 
    var self = this; 
    this.set({generatingReport: true}); 

    // By calling delay, runReport() will exit immediately so UI can redraw 
    _.delay(function() { 
    //long computation... 
    self.set({generatingReport: false}); 
    }, 50); 
} 

. 이렇게하면 runReport() 함수가 즉시 종료 될 수 있으며 이벤트의 전체 체인을 시작한 클릭 이벤트 핸들러가 실행을 완료 할 수 있고 UI는 자체를 다시 그리어 "Generating report ..."메시지를 표시 할 수 있습니다. 매우 짧은 (50 밀리 초) 지연 후 긴 계산이 시작되고 완료되면 generateReport가 false로 설정되고 UI가 다시 업데이트됩니다.

+0

안녕하세요,이 간단한 해킹이 도움이되었습니다. 이제는 두 메시지가 모두 렌더링됩니다 (1 밀리 초가 충분합니다 :). 작성한 것처럼 이것이 최적의 솔루션이라고 생각하지 않습니다. 어쨌든 감사합니다. –

+0

네, 다소 해킹 된 것 같지만, 이것이 기본적으로 어떻게해야하는지 생각합니다. Javascript (적어도 브라우저에서)는 단일 스레드 일 뿐이므로 장기 실행 작업을 수행 할 수없고 동시에 사용자 입력을 처리 할 수 ​​없습니다. 다른 사람들이 UI 스레드로 제어권을 넘겨주기 위해 장기 실행 태스크 (아마도 루핑 작업을 수행하는 코드)를 코딩하도록 제안했습니다. http://stackoverflow.com/questions/672732/prevent-long-running-javascript-lock-up-browser – heavi5ide

0

DOM 조작이 @ heavi5ide가 언급 한대로 runReport 함수보다 느리기 때문입니다.

보고서 생성이 거의 즉시 발생하는 경우 "보고서 생성 중 ..."메시지가 필요하지 않습니다. 보고서는 컴파일 0.5 초 이상 걸리는 경우에만 generatingReport 메시지를 활성화이 당신을함으로써

runReport: function() { 
    var self = this; 
    var timer = setTimeout(function() { 
     self.set({generatingReport: true}); 
    }, 500); 

    // 
    // report calculation code 
    // 

    if (this.get("generatingReport")) this.set({ generatingReport : false }); 

    clearTimeout(timer); 

} 

: 당신은 또한 같은 작업을 수행 할 수 있습니다.