2012-11-16 3 views
0

jQuery.post()에 몇 가지 추가 기능을 제공하고 싶습니다. 나는 서버에서 응답을 확인하고 다른 콜백을 호출 할 수 있기를 원한다. 예를 들어jQuery 플러그인에서 체인 콜백 메소드를 다른 사람에게 허용하려면 어떻게해야합니까?

:

$("#frmFoo").postForm("ajax") 
    .start(function() { showSpinner(); }) 
    .success(function() { alert ("Foo saved"); }) 
    .error(function() { alert ("Foo could not be saved at this time"); }) 
    .validationError(function() { alert("Please fix foo and try again"); }) 
    .complete(function() { hideSpinner(); }); 

그래서 나는 성공에 전화하거나 validationError이 validationError에 추가 정보를 제공하거나 다시 페이지 및 기반이 JSON 객체에 일관 JSON 개체를 다시 보낼 수 있어야합니다.

업데이트 가파른 학습 곡선이었으며 나는 거의 잘못된 결정을 내 렸습니다. 아래는 내가 원하는 기능에 대한 나의 시도입니다.

(function ($) { 
    $.fn.postForm = function (url) { 
     var options = options || {}; 
     var formData = this.serialize(); 
     var validationCb = jQuery.Callbacks("once memory"); 
     var successCb = jQuery.Callbacks("once memory"); 
     var errorCb = jQuery.Callbacks("once memory"); 
     var completeCb = jQuery.Callbacks("once memory"); 
     var s = jQuery.ajaxSetup({ }, options); 
     var callbackContext = s.context || s; 
     foo = { 
      success: function() { 
       successCb.add(arguments[0]); 
       return this; 
      }, 
      complete: function() { 
       completeCb.add(arguments[0]); 
       return this; 
      }, 
      validationError : function() { 
       validationCb.add(arguments[0]); 
       return this; 
      }, 
      error: function() { 
       errorCb.add(arguments[0]); 
       return this; 
      } 
     }; 
     $.post(url, formData) 
      .success(function(data, textStatus, jqXhr) { 
       if (!data.Success) { 
        validationCb.fireWith(callbackContext, [data.Message, data.KeyValuePairs]); 
       } else { 
        successCb.fireWith(callbackContext, [data, textStatus, jqXhr]); 
       } 
      }) 
      .complete(function (jqXhr, textStatus) { 
       completeCb.fireWith(callbackContext, [jqXhr, textStatus]); 
      }) 
      .error(function(jqXhr, textStatus, errorThrown) { 
       errorCb.fireWith(callbackContext, [jqXhr, textStatus, errorThrown]); 
      }); 
     return foo; 
    }; 
})(jQuery); 

내가 한 짓은 얼마나 나쁜가요? 나는 자바 스크립트와 jQuery에 익숙하지 않고 나를 물지에 묶여있는 몇 가지 규칙을 깨고 있다고 확신한다.

답변

1

promise 인터페이스를 효과적으로 변경하기 때문에 제안하는 것을 실용적이지 않습니다.

showSpinner(); 
$.post({...}) 
    .done(...)   // aka .success (deprecated) 
    .fail(...)   // aka .error (deprecated) 
    .always(stopSpinner) // aka .complete (deprecated) 

그래서, 먼저 스피너를 보여 주어야하지만 거의 모든 어려움, 그리고 : 당신은 그냥 호출자에게 $.post의 결과를 반환하는 경우 당신이 원하는 대부분이 이미 존재한다는

주 유효성 검사 오류를 잡을 방법이 없기 때문에 .done 함수의 일부 여야합니다.

+0

약속 인터페이스를 변경한다고 말하면 무슨 뜻인지 설명 할 수 있습니까? $ .post 또는 ajax 메서드 주위에 내 플러그인을 래핑 할 수 있습니까? 충돌을 피하기 위해 콜백 이름을 변경해야하는지는 신경 쓰지 않습니다. – uriDium

+0

나는 또한 좋은 속기에 콜백을 묶을 수 있기를 정말로 원합니다. – uriDium

+0

@uriDium 그게 문제 야. 당신이'$ .Deferred()'와 같은 것을 확장하거나 복제해야하는 체인에 문제가있다. - 콜백의 전체 목록을 관리하는 객체를 전달할 필요가있다. 내부의'.post()'호출이 무엇을했는지에 따라 호출됩니다. – Alnitak

0

나는 당신이 달성하고 싶은 것을 정확하게 이해한다면 $.ajax()을 사용해야합니다.

$.ajax({ 
    url: your_url, 
    type: 'POST' 
    beforeSend: function(){ showSpinner(); }, 
    error: function() { alert ("Foo could not be saved at this time"); } 
    success: function (data) { 
    if (data.validation == true) { //example of validation, depends on how you send data from backend 
     alert ("Foo saved"); 
     hideSpinner(); 
    } else { 
     alert("Please fix " + data.foo + " and try again"); //again depends on how you send data  
    } 
    } 
+0

아니요. 요점을 완전히 놓쳤습니다. json을 가로 채고 유효성 검사를 할 것인지 확인하고 사용자 지정 작업을 수행 할 후크를 제공하려고합니다. 나는 그들이 아직 무엇인지 모르며 다른 사람들이 그 일을 할 수 있기를 바란다. 팀의 다른 사람들이 사용할 플러그인으로 만들고 싶습니다. – uriDium

0

$.Deferred (또는 실제로 맞춤 설정하려는 경우 $.Callbacks) 또는 더 일반적으로는 promise pattern을 찾고 있습니다. 간단한 구현은 다음과 같이 보일 수 있습니다 :

(function ($) { 
    $.fn.postForm = function (url, options) { 
     var options = options || {}, 
      s = jQuery.ajaxSetup({ }, options), 
      callbackContext = s.context || s; 

     var formData = this.serialize(); 
     var post = $.post(url, formData); 
     var deferred = post.pipe(function(data, textStatus, jqXhr) { 
      if (!data.Success) { 
       // HTTP OK, soft error 
       return $.Deferred().rejectWith(callbackContext, [data.Message, data.KeyValuePairs]); 
      } else { 
       // success 
       return $.Deferred().resolveWith(callbackContext, [data, textStatus, jqXhr]); 
      } 
     }, function(jqXhr, textStatus, errorThrown) { 
      // HTTP error 
      return $.Deferred().rejectWith(callbackContext, [errorThrown, {}]); 
     }); 

     deferred.success = deferred.done; 
     deferred.error = deferred.fail; 
     deferred.complete = deferred.always; 

     return deferred; 
    }; 
})(jQuery); 

이것은 error/validationError를 구별하지 않습니다,하지만 biolerplate의 대부분의 코드를 제거한다.

+0

둘 사이에 구별이 필요합니다. – uriDium

관련 문제