2011-11-28 5 views
0

나는 몇 년 동안 jQuery를 사용 해왔다. 바닐라 자바 ​​스크립트에 대한 이해가 매우 제한되어있다. 범위, 객체 모델 및 자바 스크립트에서 사용되는 것으로 보이는 디자인 패턴 중 많은 것들이 나를 당황하게합니다. 내가 쓸 필요가있는 스케줄링 플러그인에서 결국 사용되는 클래스를 구현하려고하고 있는데 왜 내 클래스 멤버 중 하나에 저장된 데이터가 사용 가능한 것으로 보이지 않는지 이해하는 데 어려움을 겪고 있습니다. 문제가 범위 또는 내가 이해하지 못하는 다른 행동과 관련이 있는지 확실하지 않습니다.데이터 클래스 멤버가 직접 사용할 수없는 이유는 무엇입니까?

다음 코드는 적절한 위치의 주석에 2 개의 질문이 있습니다. 첫 번째 질문은 내 getJSON 호출에서 내 범위 해결 방법이 getJSON 내부에서 범위 문제를 처리하는 올바른 방법인지 여부입니다. 두 번째 질문은 내가 왜 schedule.data에 직접 액세스 할 수 없는지입니다.

function Schedule() { 
    this.year = null; 
    this.month = null; 
    this.day = null; 

    this.start_datetime = null; 
    this.start_timestamp = null; 
    this.end_datetime = null; 
    this.end_timestamp = null; 

    this.data = []; 

    return this; 
} 

Schedule.prototype.init = function() { 
    var url = '/tripsys/new_admin/employee_schedule/get_employee_schedule_data/' + this.start_timestamp + '/' + this.end_timestamp; 
    var self = this; // 1. trying to work around scope issues. Is this the correct way to handle the scope problems here? 
    $.getJSON(url, function(data) { 
     self.data = data; 
    }); 
} 

var schedule = new Schedule(); 

$(document).ready(function() { 
    schedule.year = $('#year').text(); 
    schedule.month = $('#month').text(); 
    schedule.day = $('#day').text(); 
    schedule.start_datetime = new Date(schedule.year, schedule.month - 1, schedule.day); 
    schedule.start_timestamp = Math.round(schedule.start_datetime.getTime()/1000); 
    schedule.end_datetime = new Date(schedule.year, schedule.month - 1, schedule.day, 23, 59, 59); 
    schedule.end_timestamp = Math.round(schedule.end_datetime.getTime()/1000); 

    schedule.init(); 
    console.log(schedule); // if I log the whole schedule object the data that I expect to be in the "data" member is there 
    console.log(schedule.data); // 2. why is the data that I expect to be in the "data" member not there when I access schedule.data directly? 
}); 

귀하의 통찰력에 감사드립니다.

+1

보조 노트에, 당신은 정말 당신이 작업하고있는 언어를 이해한다 함께, 특히 2 년 동안 그것을 사용한 후에. 주제에 대해 조금 읽는 것이 좋습니다. –

+0

동의합니다.과거에는 더 많은 백엔드 작업을 수행했으며 jQuery 추상화가 정말 멋지게 처리되는 간단한 DOM 조작보다 자바 스크립트로 더 많은 작업을 수행 할 필요가 없었습니다. 이제는 자바 스크립트에 대해 더 잘 이해할 시간입니다. 모두 도움을 주셔서 감사합니다. –

+0

아, 그게 더 합리적입니다. 나는 지금 막 웹 프로그래밍을 가르치고있다. 물론 이것은 js를 배우는 것과 관련이있다. –

답변

1

내부 함수가 jQuery에 의해 호출 될 때 함수 내에있는 this이 ajax 객체를 참조하기 때문에 계속 수행 할 수있는 동안에도 this 참조를 저장해야한다는 점에서 올바른 점입니다.

두 번째 메모에서 ajax 요청이 완료되기 전에 schedule.data을 로깅합니다. schedule을 기록 할 때 schedule.data을 볼 수 있습니다. 왜냐하면 Google 크롬에 개체를 기록 할 때 크롬 콘솔에서 개체를 수동으로 "확장"한 후에 개체 속성이 검색되기 때문입니다. 수동으로 "확장"하면 요청이 이미 완료된 것입니다.

이처럼 재현 할 수 있습니다 :

var a = {}; 
console.log(a); //do not "expand" the object properties yet 
console.log(a.property); //undefined 
a.property = "value"; 
//"expand" the already logged object and it will have "value" 
+0

네, 저는 크롬을 사용하고 있으며 콘솔에있는 객체를 "여는"예를 통해 무엇을 의미하는지 봅니다. 완벽한 설명! 감사합니다 –

1

이것은 아마도이 라인 schedule.init();에서, console.log(schedule.data);을 할 때 아직 완료되지 않은 ajax 호출을하기 때문일 것입니다. Ajax 호출은 비동기식입니다. 전화를 걸면 네트워킹 작업이 시작되고 즉시 반환됩니다. 성공 처리 함수가 호출 될 때까지 완료되지 않습니다 (그리고 self.data이 할당 된 경우입니다).

따라서 .init() 함수에서 얻은 일정 개체의 데이터를 보려면 해당 Ajax 호출이 완료 될 때까지 기다리거나 완료 함수의 데이터로 무언가를 수행해야합니다.

1
  1. 네, 많은 범위의 문제가되지 않지만 그것이 상황 문제를 해결하기 위해 변수 범위를 사용하기 때문에, 작동합니다 .

  2. schedule.data에 액세스하려면 데이터가 도착할 때까지 기다려야합니다. 즉, console.log 코드를 콜백에 배치하십시오.

1

문제는 개체를 기록하기 전에 ajax 호출이 반환되지 않는다는 것입니다. 당신이 AJAX 호출이 동기 만들고 싶어하고 init 기능을 사용하면 로그인하기 전에 결과를 얻을 경우, 아약스 jQuery를 호출에 async PARAM를 사용

$.ajax({ 
    url: url, 
    dataType: 'json', 
    async: false, 
    success: function(data){ 
     self.data = data; 
     console.log(data); 
    } 
}); 
+0

동기식 비동기 javascript 및 xxx – Esailija

+1

참고 : ajax 호출을 동기식으로 설정하면 네트워킹 작업 기간 동안 브라우저가 잠길 수 있습니다. 일반적으로 웹 앱을 코딩하는 가장 좋은 방법은 아닙니다. – jfriend00

관련 문제