2013-07-28 4 views
0

.each() 루프에서 jQuery에서 AJAX를 사용할 때 문제가 있음을 발견했습니다. 스크립트가 실행될 때 데이터베이스의 첫 번째 레코드 만 업데이트됩니다.each() 루프 내의 jQuery AJAX 솔루션

<?php 
include_once "globals.php"; 

dbConnect(); 

$isExisting = mysql_query("SELECT COUNT(userTypeId) AS userCount FROM userType WHERE userTypeId='".$_POST['userTypeId']."';"); 

$result = mysql_fetch_array($isExisting); 

//original: if(!$result['userCount'] = 0) <-- This was a logical error 
if($result['userCount'] != 0) 
    mysql_query("UPDATE userType SET userTypeName='".$_POST['userTypeName']."', isDeleted='".$_POST['isDeleted']."' WHERE userTypeId='".$_POST['userTypeId']."';"); 
else 
    mysql_query("INSERT INTO userType VALUES('', '".$_POST['userTypeName']."', '".$_POST['isDeleted']."');"); 

echo mysql_error(); 

dbClose(); 
?> 

내가 대신 비동기의 동시 사용할 수있는 옵션을 가지고 읽었습니다,하지만 난 또한 읽고 :

function save(){ 
      var _userTypeId; 
      var _userTypeName; 
      var _isDeleted; 
      var request; 

      $("tr.recUserType").each(function(){ 
       $this = $(this); 
       _userTypeId = $this.find("#userTypeId").html(); 
       _userTypeName = $this.find("#userTypeName").val(); 
       _isDeleted = $this.find("#isDeleted").val(); 

       request = $.ajax({ 
        url: "save.php", 
        type: "POST", 
        data: {userTypeId: _userTypeId, userTypeName: _userTypeName, isDeleted: _isDeleted} 
       }); 
      }); 

      request.done(function(){ 
       document.location.reload(); 
      }); 

      request.fail(function(){ 
       alert("Request Failed!"); 
      }); 
     } 

그리고 save.php의 내용 : 여기

내 스크립트입니다 그것은 좋은 습관이 아닙니다.

어떻게하면 실제로 비동기 적으로 완료되고 문제를 해결할 수 있습니까?

+0

각 루프마다 동일한 'userTypeId' -'_userTypeId = $ this.find ("# userTypeId"). html();'을 사용하므로 1 행만 업데이트 할 것입니다. – Sean

+1

'POST userTypeName = Lolinjection & isDeleted = 1 & userTypeId = '또는 OR 1 = 1; --' 그리고 SQL 주입이 나쁜 방법을 설명합니다. 실제로 이것을 막거나 최소한 입력 내용을 살균하는 데 도움이되는 라이브러리를 사용하십시오. – Amelia

+0

@Sean, 동일한 ID가 있어도 태그를 반복 할 경우 userTypeId 값이 어떻게 같을 지 잘 모르겠습니다. –

답변

4

jQuery의 $ .ajax()는 jQuery XMLHttpRequest 객체 ("jqXHR")를 반환합니다. 이 객체를 "응답"변수에 저장하고 있습니다.

귀하의 문제는 범위입니다. jqXHR의 N을 모두 동일한 "요청"변수에 저장하고 있습니다. 루프가 끝날 때까지 "요청"은 마지막 jqXHR을 가리키고 있으므로 .done()은 마지막 요청이 완료 될 때만 호출됩니다.

Karl Anderson은 Karl Anderson이 지적했듯이 모든 jqXHR을 배열에 저장 한 다음 모든 호출이 [비동기 적으로] 완료되면 단일 콜백을 실행해야합니다.

또한 $ .ajax()의 "async : false"를 사용하려는 유혹을 피하십시오. 요청이 완료 될 때까지 브라우저가 강제로 중지되며 이는 나쁘다. 거의 항상 $를 성취 할 수 있습니다.ajax() 비동기 호출; 그것은 약간의 교활함을 필요로 할지도 모르지만 확실히 더 나은 것을 위해있을 것입니다.

+0

어떤 이유로 jqXHR 객체를 배열 내에 저장 한 후에도 여전히 작동하지 않습니다. 나는 당신이 말하는 것에 대한 개념을 가지고 있는데 왜 효과가 없는지 확신하지 못합니다. –

+2

어쩌면 시도해보십시오 : var defer = $ .when.apply ($, jqXHRs); defer.then (function() {...}); (http://stackoverflow.com/questions/9865586/jquery-when-troubleshooting-with-variable-number-of-arguments Andy의 답변 참조) – Jackson

0

문제가 코드 블록에 있습니다, 작업이 비동기이기 때문에,이 라인은 저장하기 전에 실행중인

request.done(function(){ 
    document.location.reload(); 
}); 

완료되어 완료되지 저장하여 후에 첫째, done 로직을 실행 .

jQuery .when()/.then() 함수를 사용하여 로직을 진행하기 전에 모두 실행될 때까지 기다릴 수있는 지연된 오브젝트의 배열을 작성해야합니다.

다음은이 상황을 설정하는 방법을 자세히 설명하는 이전 StackOverflow 질문입니다. 허용되는 답변 jQuery when each is completede trigger function을 읽으십시오.

0

여기 몇 가지 일이 있습니다.

(루프 밖에서 범위) 루프에서 request 변수를 다시 사용하여
  1. 는 루프의 매 반복이 무엇 겹쳐 요청에 새로운 객체를 할당한다. 이는 마지막 반복에 대한 응답 핸들러 만 설정한다는 것을 의미합니다.

  2. 당신의 request.done 방법 당신은 루프의 각 반복에 대해 동일한 userTypeId을 찾고 @Sean

  3. 에서 언급 한 바와 같이 실제로 ...

  4. 를 다른 요청을 중단하고 할 페이지를 다시로드

+0

# 3과 관련하여 이제는 더 명확 해집니다. 각 태그의 userTypeId가 동일한 경우 문제가됩니까? 각 을 반복 할 것이기 때문에 각 반복마다 동일한 userTypeId가되지는 않습니다. 맞습니까, 아니면 뭔가 빠졌습니까? –

+0

당신이'# userTypeId'를 사용하고 있기 때문에, (id = "userTypeId" "를 가진 페이지상의 요소들을 찾고 있습니다. 그러나 당신이 부모 tr에 대한 검색 범위를 지정하고 있기 때문에,이 경우에는 잘 될지 모르지만, 코드는 클래스 또는 다른 것을 사용하여 더 깨끗하게 만들 수 있습니다. – lemieuxster