2012-10-22 4 views
0

간단한 자바 스크립트 폼을 작성하고 있습니다. 각 버튼 옆에 버튼이있는 장치 목록으로, 장치에 대한 정보를 편집 할 수있는 텍스트 필드로 연결됩니다. 대신 모든 버튼을 사용하면 목록의 마지막 장치에 대한 정보로 이동합니다. 여기에 내가 목록을 만드는거야 코드 조각은 다음과 같습니다함수 선언에서 변수를 평가하는 방법?

for(var i in portal.clients){ 
    var row = document.createElement('tr'); 
    var cell2 = document.createElement('td'); 
    var button = document.createElement('button') 
    var title = document.createTextNode("Edit Config") 
    button.appendChild(title) 
    button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)} 
    cell2.appendChild(button) 
    row.appendChild(button) 

    var cell1 = document.createElement('td'); 
    var client = document.createTextNode(portal.clients[i].info.description.name) 
    cell1.appendChild(client) 
    row.appendChild(cell1) 
    table.appendChild(row); 
} 

나는 문제가 버튼을 대신 클릭 할 때 내가 의미처럼 함수가 선언 될 때 onClick 함수 선언에서 i 평가하기 것을 가정 그것까지. 함수를 선언 할 때 변수를 강제로 평가할 수있는 방법이 있습니까? 아니면 함수에 클라이언트 인덱스를 전달하는 데 사용해야하는 다른 방법이 있습니까?

+0

이 질문을보십시오 http : //stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – agradl

답변

3

언제 당신은 새 범위에서 변수를 캡처해야합니다.

for(var i in portal.clients){ 
    (function(i){ 
     // do something later with i 
    })(i); 
} 

JavaScript의 범위 지정과 관련하여 많은 논의가 있습니다. 중요한 방식으로 JavaScript를 이해하는 것이 필수적이므로 꼭 읽어 보시기 바랍니다.

+1

감사! 범위 지정 외에,이 질문에 대한 답을 찾기 위해 검색해야 할 부분이 있습니까? 내 JavaScript 용어는 여전히 약하다. – Azdle

+0

@Azdle "JavaScript closure"와 "Javascript scope"는 시작하기 좋은 곳입니다. – Matt

+0

차가움. 도와 주셔서 감사합니다! – Azdle

0

루프를 자체 실행 기능에 넣으면 문제를 해결할 수 있습니다. 테스트되지 않은 예 : 당신은 콜백 (루프가 완료 될 때까지 평가되지 않습니다 즉 뭔가를) 당신의 반복 변수 i를 사용하려면

for(var i in portal.clients){ 
    (function (i) { 
    var row = document.createElement('tr'); 
    var cell2 = document.createElement('td'); 
    var button = document.createElement('button') 
    var title = document.createTextNode("Edit Config") 
    button.appendChild(title) 
    button.onclick = function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)} 
    cell2.appendChild(button) 
    row.appendChild(button) 

    var cell1 = document.createElement('td'); 
    var client = document.createTextNode(portal.clients[i].info.description.name) 
    cell1.appendChild(client) 
    row.appendChild(cell1) 
    table.appendChild(row); 
    })(i); 
} 
1

각 반복마다 i 사본이있는 새 범위를 만들어야합니다. 제공하는 코드에서 즉시 실행되는 함수를 작성하여 새 범위를 만들 수 있으며 연결된 새 범위에서 변수와 함께 사용하려는 실제 함수를 반환합니다.

for(var i in portal.clients) { 
    var row = document.createElement('tr'); 
    var cell2 = document.createElement('td'); 
    var button = document.createElement('button') 
    var title = document.createTextNode("Edit Config") 
    button.appendChild(title) 
    button.onclick = (function(i){return function(){displaySettingsPage(portal.clients[i]); console.log("Showing client: " + clientNum)}; })(i); 
    cell2.appendChild(button) 
    row.appendChild(button) 

    var cell1 = document.createElement('td'); 
    var client = document.createTextNode(portal.clients[i].info.description.name) 
    cell1.appendChild(client) 
    row.appendChild(cell1) 
    table.appendChild(row); 
} 
+0

좋아, 그 작동하지만 왜 이해가 안 돼요. 왜이 경우에 선언되었지만 원래 코드에서는 평가되지 않았습니까? 편집 : 아, 매트의 응답에서 이해합니다. 감사! – Azdle

+0

@Azdle 편집을 참조하십시오. 기본적으로'(function() {})();'구문에 의해 즉시 실행되는 추가 함수가 있습니다.이 함수는 코드를 직접 작성하는 것과 동일하지만 새로운 스코프 만들어집니다. '(function() {}) (i); '을 사용하여 새로운 범위에'i'를 전달하고 실제 함수를 리턴하기 위해 그것을 사용합니다. – Mahn

관련 문제