...More Simple More Efficient... ☞ Guest Book enSimple.net ?
Home Study Q & A Knowledge Base Free Board News

   WEB forever
[작성자 : chang]  11/4/2009 12:46:17 PM  에 남기신 글입니다.

제목 : ASP.NET AJAX : Microsoft AJAX Library 여러가지 팁(?)
이번 글은 ASP.NET AJAX 활용에 필요한 여러가지 내용을 두서없이 적어보았다. 개발자가 알아두면 좋을 내용들이라 판단되어 적었는데,,,,, 사실...나중에 아수울때 빨리 확인하기 위한...기록의 의미가 강하다. 참고 바란다.

JavaScript 함수 컨텍스트(Context)

함수가 실행하는 환경(Context) 정도로 이해할 수 있는 개념이다. 일반적인 JavaScript 함수의 기본 컨텍스트는 window 객체이다. 그리고 이 컨텍스트는 함수 내에서 this 키워드로 접근할 수 있다. 따라서 아래의 예제에서 표시될 메시지는 "Window1" 이 된다.

<script type="text/javascript">
<!--
 window.name = "Window1"; // this.name="Window1" 과 동일
 function someFunc()
 {
  alert(this.name);
 }
 someFunc();
//-->
</script>

그러나 함수가 어떤 객체의 메서드로서 지정된 경우, 함수의 컨텍스트는 그 객체로 설정된다. 따라서 아래 예제에서 표시될 메시지는 "Object1"이 된다.

<script type="text/javascript">
<!--
 window.name = "Window1"; // this.name="Window1" 과 동일
 var o = new Object();
 o.name="Object1";
 
 function someFunc2()
 {
  alert(this.name);
 }
 o.doSomething = someFunc2;
 
 //혹은 아래와 같이 객체 메서드로 지정할 수도 있다.
 //o.doSomething = function() { 
 //    alert(this.name);
 // }
 
 o.doSomething();
//-->
</script>

한가지 흥미로운 점이 더 있는데, 먼저 아래의 예제를 실행하면 결과가 어떻게 나올까?

<script type="text/javascript">
<!--
 window.name = "Window1"; // this.name="Window1" 과 동일

 function someFunc2() {
     alert(this.name);
 }
 someFunc2();
 new someFunc2();
//-->
</script>

처음은 "Window1"으로 표시되고 그 다음은 "undefined"로 나온다. 즉 첫 번째 호출에서 함수의 컨텍스트는 window 객체이고, 두번째 호출에서는 함수의 컨텍스트가 window 객체가 아닌 다른 것이라는 말이 된다. 그렇다 두 번째 호출에서는 새로이 생성된 빈 Object 객체가 함수의 컨텍스트가 된다.
이유인즉슨,  첫 번째 호출은 다시 설명하지 않아도 알 것이고, 두 번째 호출의 경우, new 연산자는 새롭고 빈 Object 인스턴스를 (내부적으로) 생성한 다음에 함수를 호출하므로, 이 함수의 컨텍스트는 생성된 Object 객체가 된다. someFunc() 함수는 생성된 Object 객체의 생성자가 된다.
결과적으로 이 빈 객체에는 name 속성이 정의되지 않았으므로 undefined 결과가 표시되는 것이다.

클라이언트 측 델리게이트로서 이벤트 핸들러 등록

델리게이트는 우리가 알다시피 함수 포인터 개념과 유사하다. 따라서 이벤트 핸들러 등록시에 함수명을 넘겨주는 것은 곧 해당 함수에 대한 포인터를 넘겨주는 거라 볼 수 있다.
그렇다면 거기에 함수 이름 대신 델리게이트를 생성하여 넘겨 줄 수도 있다는 결론이 나온다.
중요한 것은, 델리게이트 생성시에 대상이 되는 함수 컨텍스트를 미리 매개 변수로 지정하여 해당 함수 실행 시 그 컨텍스트를 결정할 수 있다는 점이다.
그래서 아래의 예제처럼 우리는 클라이언트 델리게이트를 직접 생성하여 $addHandler의 매개 변수로 전달할 수 있고, 함수 Context로서 this(예제의 경우 window 객체가 된다)를
미리 결정하여 전달하고 있다.

<input type="button" id="testButton" value="Click Me" />
<script type="text/javascript">
<!--
 
 function pageLoad() {
 this.test = "I'm a test string!";
 var clickDelegate = Type.createDelegate(this, onButtonClick);
 $addHandler($get('testButton'), 'click', clickDelegate);
 }
 function onButtonClick() {
 alert(this.test);
 }
//-->
</script>

★ [Tip] JavaScript Function 개체의 별칭이 Type이므로 Function.createDelegate()로 호출해도 된다.

버튼을 클릭하면 이벤트 핸들러(함수)의 현재 컨텍스트를 나타내는 this의 test 속성 값으로 "I'm a test string!" 이라는 문자열 메시지가 표시된다. 즉 미리 지정했던 window 객체의 test 속성값이 표시되는 것이다.

만일 위의 예제에서 $addHandler를 아래와 같이 델리게이트를 쓰지 않고 그냥 함수이름을 지정하는 것과 무엇이 다를까?

$addHandler($get('testButton'), 'click', onButtonClick);

위와 같이 변경하면 alert(this.test) 구문은 이전과 달리 undifined 메시지를 표시한다. 그 이유는 this가 가리키는 객체가 testButton이 되었기 때문이다. $addHandler의 경우 내부적으로 델리게이트 자동으로 생성하여 주는데 그 과정에서 함수의 컨텍스트를 testButton으로 설정하는 것이다.
따라서, 위의 onButtonClick과 같은 이벤트 핸들러(함수) 내에서도 컨텍스트(this)를 windows 객체나 다른 객체로 유지하고 싶다면 클라이언트 델리게이트를 직접 생성하여 전달토록 한다.
굳이 필요 없는 내용인가? 이런 게 존재한다는 사실을 모르면 결정적인 순간에 지름길을 두고 돌아서 가야 하는 비효율을 낮기 쉽상이다 그래서 언급해 보았다.(사실은 메모해 놓은 게 아까워서 넣었다..-_-!)

Microsoft Ajax Library에서는 $addHandlers 도 제공하는데 이 함수에서는 함수의 컨텍스트를 매개변수로 지정할 수 있도록 제공한다.

$addHandlers(button, {
            'mouseover': button_OnMouseOver,
            'mouseout': button_OnMouseOut
        }, this);

 $clearHandlers 메서드는 $addHandler나 $addHandlers에 의해 등록된 모든 이벤트 핸들러를 제거하고 관련된 모든 델리게이트를 소멸해 준다.

클라이언트 측 콜백(Callback)으로서 이벤트 핸들러 등록

콜백의 의미는 우리가 알고 있듯이 어떤 함수의 처리가 완료된 후 역으로 호출한 넘에게 결과를 알려주기 위해 역으로 호출해 주는 행위를 말한다. 콜백함수란 그런한 역 호출의 대상이 되는 함수를 말한다. 주로 비동기 함수 호출에서 호출 간의 동기화를 위해 사용되는 프로그래밍 기법이다.
클라이언트 스크립트에서도 우리는 콜백을 구현할 수 있는데, 이게 중요한 건 우리가 비동기 HTTP 요청을 하기 때문에 그 요청의 완료 시점과 완료에 대한 대응 처리를 위해서 이 콜백 메카니즘이 필요한 것이다.
아래의 예제 처럼 콜백도 일종의 함수 포인터로 이해해도 좋다. 따라서 $addHandler 의 매개 변수로서 전달 할 수 있다.
중요한 점은 콜백 생성시에 콜백 함수와 함께 함수에 전달할 매개변수를 지정할 수 있다는 것이다.

<input type="button" id="myButton" value="Time elapsed since page load" />
<script type="text/javascript">
 <!--
 function pageLoad() {
 var someData = { date : new Date() };
 var clickCallback = Type.createCallback(onButtonClick, someData );
 $addHandler($get('myButton'), 'click', clickCallback);
 }
 function onButtonClick(evt, passedData) {
 var loadTime = passedData.date;
 var elapsed = new Date() - loadTime;
 alert((elapsed / 1000) + ' seconds');
 }
 //-->
</script>


콜백 생성 시에 전달한 데이터를  그대로 호출 시점에 활용할 수 있다는 점이 중요하고, 또한 이벤트 객체(System.UI.DomEvent 객체)도 같이 매개 변수로 전달되므로 이벤트 속성정보를 확인할 수도 있다.
콜백 함수의 컨텍스트는 $addHandler의 기본 동작에 의해 myButton 객체가 된다.

JSON 다루기

 Microsoft Ajax Library 는 JSON 직렬화를 위해 Sys.Serialization.JavaScriptSerializer 객체를 제공한다. 이 개체는 직렬화와 역 직렬화를 위해 아래의 두 메서드를 제공한다.
 ○ serialize
 ○ deserialize

serialize 메서드의 경우 매개 변수로서 JavaScript 객체를 받아들이고 결과로서 직렬화된 문자열을 리턴한다.
간단하게 사용법을 보도록 하자.

function testJSON() {
    // JSON 표기로서  객체(customer)를 생성한다.
     var customer = { firstName: 'DeukChang', lastName: 'Park' };
     var serializer = Sys.Serialization.JavaScriptSerializer;
     var json = serializer.serialize(customer);
     var customer = serializer.deserialize(json);
     alert("Original: " + customer.firstName + customer.lastName + "\r\n" + "JSON: " + json);
 }
 
<input type="button" id="btnTestJSON" value="JSON Serialization" onclick="testJSON()" />

결과는 아래와 같다.



비동기 포스트백 취소와 중지

처리 중인 비동기 포스트 백을 중지하거나 새로운 비동기 포스트백 요청을 취소하는 방법은 아래와 같다.
 ○ 처리 중인 비동기 포스트백을 중지하려면, PageRequestManager 클래스의 abortPostback 메서드를 호출한다.
 ○ 새로운 비동기 포스트백을 취소하려면 PageRequestManager 클래스의 initializeRequest 이벤트 발생 시(이벤트 핸들러에서) cancel 속성 값을 true로 설정한다.

※ 첨부 파일 참조

 Sys.Application.add_load(ApplicationLoadHandler)
 function ApplicationLoadHandler(sender, args)
 {
      Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(InitializeRequest);
 }
 function InitializeRequest(sender, args)
 {
  var prm = Sys.WebForms.PageRequestManager.getInstance();
  if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'CancelRefresh')
   prm.abortPostBack();
  else if (prm.get_isInAsyncPostBack() & args.get_postBackElement().id == 'RefreshButton') {
   args.set_cancel(true);
 }


이번 글로서 ASP.NET AJAX 에 관련된 글을 일단 마무리하고자 한다. 그동안 열화(?)와 같은 성원(?)을 해주신 엔심플 독자 여러분에게 감사 드린다으..
필자 지금 ASP.NET MVC 관련한 책도 번역 중이고, 프로젝트도 준비 중이다...곧 ASP.NET MVC 프레임웍에 대한 이야기로 찾아올 것이다으...

I'll be back...sooooon

첨부파일 : Stop_CancelPostback.zip (2 Kbytes)       
List
□ 한줄의 평 이름: