Silverlight를 설치하려면 여기를 클릭합니다.*
Korea 대한민국변경|Microsoft 전체 사이트
MSDN
|개발자 센터
MSDN Home   MSDN Home

Cutting Edge
ASP.NET "Atlas"를 사용한 작업 진행률 표시줄 구현 간소화


이 문서에 사용된 코드 다운로드: CuttingEdge2006_10.exe (555KB)

Dino Esposito (영문)

목차
Atlas의 원격 호출 피드백
업데이트 가능한 Atlas 패널
진행률 표시줄 추가
트리거 추가
상황에 맞는 피드백
요약


지난달에는 ASP.NET 웹 응용 프로그램과 관련하여 진행률 표시줄에 대해 설명하고 기본 제공 스크립트 콜백 API를 기반으로 한 구현을 제시했습니다(www.microsoft.com/korea/msdn/msdnmag/issues/06/09/cuttingedge/ 참조). 시간이 오래 걸릴 수 있는 작업이 진행되는 동안 사용자에게 간단한 피드백을 제공하는 것은 어려운 일이 아닙니다. 다시 게시를 수행하는 단추에 간단한 JavaScript 코드를 연결하고 "잠시 기다려 주십시오…"와 같은 비교적 정적인 메시지를 표시하도록 하면 됩니다. 그러나 해당 페이지에 일반적인 다시 게시가 사용되는 경우 정적인 메시지 이상은 표시할 수 없습니다. 예를 들어 애니메이션을 추가한다고 해도 브라우저가 현재 페이지를 동결하고 다음 응답 및 다음 페이지를 준비하기 때문에 이 애니메이션은 시작되지 않습니다. 더 나은 사용자 환경을 만들려면 대역 외 호출을 활용할 수 있습니다. ASP.NET 스크립트 콜백 API는 현재 페이지를 벗어나지 않고도 비동기 호출을 수행할 수 있는 기능을 제공하지만 복잡한 작업을 수행하기에는 전반적인 프로그래밍 모델이 다소 불완전합니다.

지난달 기사에서는 스크립트 콜백 API의 모든 기능을 동원하여 정적 피드백 및 상황에 맞는 피드백을 구현했습니다. 특히 상황에 맞는 피드백은 원격 작업의 진행에 따라 사용자에게 다른 메시지를 보여 주어야 하는데, 이는 구현하기가 어렵습니다. 모든 호출은 대역 외 방식으로 작동하면서 클라이언트로 데이터를 보고하며, 클라이언트에서는 JavaScript 코드가 현재 페이지를 업데이트합니다.

즉, 스크립트 콜백 API를 사용하면 진행 중인 작업 모니터링을 중심으로 파생되는 거의 모든 기능을 코드로 작성할 수 있습니다. 그러나 이를 통해 산출된 코드는 초보 개발자가 읽고 유지 관리하기에 쉽지 않습니다. 대안으로 ASP.NET "Atlas"는 어떨까요? Atlas는 AJAX 스타일의 기능을 ASP.NET 2.0 플랫폼에 구현해 주는 프레임워크입니다. 비슷한 다른 프레임워크와 달리 Atlas는 ASP.NET에 포함되도록 디자인되었으므로 기존 플랫폼 및 응용 프로그램 모델과 매끄럽게 통합됩니다.

Atlas에는 AJAX 코딩을 쉽게 해주는 구성 요소, 컨트롤 및 동작 집합이 제공되며, 더 중요한 점은 이들 대부분이 ASP.NET 개발자 관점에서 투명하게 작동한다는 것입니다. 클라이언트 쪽에서 Atlas는 클라이언트 UI 프레임워크 및 스크립트 구성 요소 모델을 토대로 풍부한 대화식 기능을 신속하고 효율적으로 디자인하며 서버 쪽에서는 AJAX 기능을 간단하게 구현할 수 있도록 지원하는 새로운 컨트롤 모음을 제공합니다. 전체 Atlas 기능 집합에 대한 개요는 MSDN®Magazine 2006년 7월호에 수록된 Matt Gibbs의 기사(www.microsoft.com/korea/msdn/msdnmag/issues/06/07/AtlasAtLast/)를 참조하십시오.

이 기사에서는 이전 Cutting Edge 기사에서 설명했던 모든 예를 Atlas를 사용하여 다시 작성할 것입니다. 훨씬 단순하고 깔끔한 방법으로 정적 및 상황에 맞는 진행률 표시줄을 구현하는 방법을 확인할 수 있을 것입니다.


Atlas의 원격 호출 피드백

특정 기능이나 기술을 설명하기 위한 예는 간단하고 표준적이어야 하는 경우도 있지만 그렇지 않은 경우도 있습니다. 바로 이 기사가 그런 경우로, 여기에서는 기반 프레임워크의 잠재력을 끌어내 그 기능을 사용하는 최선의 방법을 판단할 수 있도록 도움을 제공하기 위해 보다 현실적인 예를 제시할 것입니다. SQL Server™ Northwind 데이터베이스 테이블의 간단한 데이터 액세스 계층부터 시작하겠습니다. 그림 1에서와 같이 쿼리를 감싸는 간단한 래퍼인 몇 가지 메서드를 포함하는 CoreDataService 클래스를 만들었습니다. 그림에서 볼 수 있듯이 대부분의 메서드는 ADO.NET DataTable 개체를 반환합니다.

샘플 Atlas 응용 프로그램을 작성하기 위해 최신 CTP(Community Technology Preview)와 함께 설치되는 Atlas Visual Studio® 2005 템플릿을 사용했습니다. 그림 2 에서는 스크립트를 제외한 페이지 태그를 보여 줍니다. 페이지에는 각각 연도 및 직원 이름을 선택하기 위한 드롭다운 목록 컨트롤 두 개가 포함되어 있습니다. HTML 버튼을 통해 사용자 인터페이스가 완성됩니다. 이 예에서 버튼 컨트롤이 수행하는 작업은 입력 필드를 제출하는 것이 전부이므로 표준 <asp:Button> 태그를 사용할 필요는 없습니다. 제출 단추 클릭은 브라우저에서 처리되며 일반적인 다시 게시를 통해 해결됩니다. 대역 외 호출을 사용하기 위해 클라이언트 쪽 단추와 약간의 JavaScript가 필요합니다.

Atlas에서 스크립트를 통해 호출 가능한 원격 메서드를 정의하는 방법에는 웹 서비스를 사용하는 방법과 페이지 메서드를 사용하는 방법, 두 가지가 있습니다. ASP.NET 웹 서비스에 정의된 웹 메서드를 호출하거나 같은 페이지 클래스에 정의된 임시 메서드를 호출할 수 있습니다. 범위가 페이지 경계를 넘지 않는 간단한 솔루션을 작성하고 구성하는 데는 분명 페이지 메서드가 빠른 해결 방법입니다. 반면 웹 서비스를 사용하면 재사용 가능성 및 상호 운용성이 강화됩니다. 현재 Atlas는 ASMX 리소스로 표시되는 ASP.NET 웹 서비스를 지원하지만 앞으로는 SVC 리소스로 표시되고 IIS에서 호스팅하는 Windows® Communication Foundation 서비스도 지원할 것입니다. 여기에서는 간단한 구현을 위해서 페이지 메서드를 선택했지만 래퍼 웹 서비스에 CoreDataService 클래스를 손쉽게 캡슐화할 수 있습니다. 프록시 클래스를 만들고 WebMethod 특성을 사용하여 해당 프록시의 메서드를 장식하기만 하면 됩니다.

특정 페이지를 응용 프로그램 컨텍스트 내의 웹 서비스로 게시하는 데 사용할 수 있는 페이지 메서드 집합이 있습니다. 다음과 같이 스크립트 태그를 사용하여 Atlas 원격 호출에서 사용 가능한 페이지 메서드를 정의할 수 있습니다.

<script type="text/VB" runat="server">
   <WebMethod()> _
   Public Function GetSalesByEmployee( _
           ByVal id As Integer, _
           ByVal year As Integer) As Decimal
       Return GetSalesByEmployeeInternal(id, year)
   End Function
</script>

스크립트 태그의 내용은 Visual Basic® 또는 C#으로 표시됩니다. 표준적인 WebMethod 특성을 사용하여 메서드를 장식하고 외부 호출자가 보게 될 끝점을 정의합니다. 개인적으로는 코드 숨김 클래스의 내부적으로 보호되는 메서드를 통해 메서드 본문을 참조하는 방법을 선호하지만 필요하다면 어떤 코드라도 인라인으로 포함할 수 있습니다. WebMethod 특성을 사용하려면 ASPX 페이지에 올바른 네임스페이스를 비롯해 반환 값 및 입력 매개 변수에 필요한 네임스페이스를 가져와야 합니다.

<%@ Import Namespace="System.Web.Services" %>

GetSalesByEmployeeInternal 메서드는 도우미 데이터 서비스를 호출하여 지정한 연도에서 해당 직원의 총 판매량을 얻고 값을 반환합니다.

Function GetSalesByEmployeeInternal( _
        ByVal id As Integer, ByVal year As Integer) As Decimal
    Dim helper As New FakeDataService
    Return helper.GetSalesByEmployee(id, year)
End Function

메서드가 그림 1의 CoreDataService 대신 FakeDataService 클래스를 사용한 이유는 무엇일까요? FakeDataService는 진행률 표시줄의 동작을 좀 더 확실히 테스트할 수 있도록 CoreDataService 클래스를 미러링하고 약간의 대기 시간을 추가합니다만, 물론 프로덕션 응용 프로그램에는 이러한 대기 시간을 넣을 이유가 없을 것입니다.

Public Function GetSalesByEmployee( _
        ByVal empID As Integer, ByVal year As Integer) As Decimal
    Thread.Sleep(5000)
    Return coreDataService.GetSalesByEmployee(empID, year)
End Function

원격 호출을 시작하고 결과를 페이지에 통합하려면 어떻게 해야 할까요? 호출을 트리거하고 결과를 처리하는 데에도 약간의 JavaScript 코드가 필요합니다. 그림 3은 샘플 ASPX 페이지에 필요한 코드를 보여 줍니다.

findData 메서드는 입력 단추의 클릭 이벤트에 연결됩니다. 이 메서드는 드롭다운 목록에서 선택된 값을 수집하고 진행률 표시줄 사용자 인터페이스를 켭니다. 스크립트는 마지막으로 다음과 같은 코드를 실행합니다.

PageMethods.GetSalesByEmployee(id, year, onSearchComplete);

PageMethods 개체는 Atlas 인프라가 텍스트/VB 스크립트 블록의 내용을 바탕으로 만든 JavaScript 프록시입니다. 이 개체는 페이지에 선언된 웹 메서드 수만큼 메서드를 나열합니다. 각 메서드의 서명은 해당하는 웹 메서드의 서명에 사용자 인터페이스를 업데이트하는 데 사용되는 콜백 매개 변수를 추가한 것과 일치합니다. onSearchComplete 개체는 진행률 표시줄을 해제하고 받은 데이터를 보여 주는 JavaScript 함수입니다.

전반적인 Atlas 코드는 ASP.NET 스크립트 콜백을 사용하는 코드만큼 복잡하진 않지만 JavaScript 기술을 요구합니다. 진행률 표시줄 블록에 원하는 텍스트와 애니메이션을 넣을 수 있으며 이는 비동기 호출 기간 동안 페이지에 표시됩니다. 그림 4는 동작하고 있는 샘플 페이지를 보여 줍니다.

그림 4 Atlas를 사용한 WebMethod 호출
그림 4 Atlas를 사용한 WebMethod 호출 (크게 보려면 이미지를 클릭하십시오.)

그림에서 실행되는 웹 페이지 메서드는 지정한 직원이 처리한 전체 주문의 수를 스칼라 값으로 반환합니다. 웹 페이지 메서드가 데이터 테이블을 반환하는 경우에는 맞춤 구성된 바인딩 메커니즘이 필요합니다. Atlas serialization 엔진 덕분에 ADO.NET DataTable 개체를 올바르게 JavaScript 개체로 serialize할 수 있습니다. 요점은 이 개체를 테이블과 유사한 HTML 구조에 매핑하기 위해서는 읽기 어렵고 유지 관리도 힘든 많은 양의 코드가 필요하다는 것입니다.

Atlas는 클라이언트 데이터 바인딩을 위한 고급 자동 기능을 제공합니다. 이러한 기능 집합을 사용하기 위해서는 새로운 프로그래밍 모델을 익혀야 하며, 보유한 JavaScript 기술을 보완 또는 향상시켜야 합니다. 다행히 이러한 방법만 가능한 것은 아닙니다. Atlas에는 강력하면서도 익숙한 프로그래밍 모델을 제공하는 서버 기반 API도 포함되어 있는데, 더 중요한 사실은 이 API가 진행률 표시줄을 기본 지원한다는 점입니다. 서버 쪽 API는 UpdatePanel이라는 새로운 컨트롤을 중심으로 구성되어 있습니다.


페이지 맨 위로페이지 맨 위로

업데이트 가능한 Atlas 패널

UpdatePanel 서버 컨트롤은 자동 대역 외 기능으로 ASP.NET 패널 컨트롤을 확장합니다. Atlas는 UpdatePanel 컨트롤의 내용을 다시 게시 및 부분 렌더링될 수 있는 일종의 하위 폼으로 간주합니다. 다시 게시는 스크립트를 통해 비동기적인 방식으로 수행됩니다. 패널의 입력 필드 및 다른 숨겨진 필드만 송수신됩니다. 또한 게시가 완료될 때 패널의 컨트롤에서 생성한 태그만 클라이언트에서 새로 고쳐집니다. 부분적인 페이지 다시 게시를 트리거하는 방법은 다양하지만 여기에서는 가장 간단한 시나리오를 먼저 살펴보겠습니다.

그림 5는 UpdatePanel 컨트롤을 사용한 Atlas 페이지를 보여 줍니다. 이와 유사한 Atlas 페이지에는 두 가지 다시 게시 방법, 즉 기존 ASP.NET의 일반적인 전체 다시 게시와 패널을 사용한 부분 다시 게시를 사용할 수 있습니다. 패널의 다시 게시를 트리거하는 이벤트가 발생하면 UpdatePanel 컨트롤의 ContentTemplate 태그에 포함된 모든 컨트롤은 현재 컨트롤의 내용을 대역 외 호출을 사용하여 서버로 다시 게시합니다. 이러한 호출의 응답으로 DHTML을 사용하여 클라이언트 페이지에서 대체하기 위한 태그가 서버에서 새로 생성됩니다. 다행스러운 점은 이러한 작업을 수행하는 데 필요한 스크립트를 익히거나 HTML 대체에 대해 신경 쓸 필요가 없다는 것입니다. 필요한 모든 스크립트 코드는 UpdatePanel 컨트롤이 생성합니다.

UpdatePanel 컨트롤이 예상대로 동작하도록 하려면 ScriptManager 컨트롤의 EnablePartialRendering 속성을 다음과 같이 설정해야 합니다.

<atlas:ScriptManager ID="ScriptManager1" runat="server" 
    EnablePartialRendering="True" />

모든 Atlas 페이지는 정확하게 ScriptManager 서버 컨트롤 인스턴스 한 개로 표현됩니다. Microsoft.Web.UI 네임스페이스에 정의된 ScriptManager는 대부분의 Atlas 서버 인프라를 담당하는 두뇌 역할을 하며 많은 수의 클라이언트 기능을 조율하는 역할도 합니다. 예를 들어 ScriptManager 컨트롤은 웹 서비스를 참조하고 서버 컨트롤을 확장하는 일련의 스크립트를 발행하는 기능을 담당합니다. 또한 ScriptManager는 UpdatePanel 컨트롤을 통해 클라이언트 페이지를 부분적으로 업데이트하는 작업도 담당합니다. EnablePartialRendering 속성 설정을 기본값인 false로 두면 UpdatePanel 컨트롤은 기존의 패널 컨트롤과 똑같이 동작합니다.

UpdatePanel 컨트롤의 내용 템플릿에 단추 컨트롤이 포함되어 있으면 사용자가 이러한 단추를 클릭할 때마다 다시 게시가 발생합니다. 이외에도 Atlas 패널의 새로 고침을 트리거하는 여러 다른 이벤트가 있습니다. 이에 대한 내용은 조금 뒤에 다시 설명하겠습니다.. 우선은 그림 5에 예시된 페이지에 초점을 맞추겠습니다. 이 UpdatePanel 컨트롤은 다음과 같은 표, 레이블 및 제출 단추를 포함하고 있습니다.

<atlas:UpdatePanel runat="server" ID="UpdatePanel1">
    <ContentTemplate>
        <asp:Button ID="Button1" runat="server" Text="Load" 
            OnClick="Button1_Click" />    
        <asp:GridView ID="GridView1" runat="server" 
            DataSourceID="DataServiceSource"
            AllowPaging="True" />
        <smal><asp:Label runat="server" ID="TimeServed" /></small>
    </ContentTemplate>
</atlas:UpdatePanel>

이 표는 지정한 연도에 지정한 직원이 처리한 모든 주문을 포함하기 위한 것으로 ObjectDataSource 컨트롤과 바인딩되고 이어 FakeDataService 클래스를 통해 데이터를 검색합니다.

<asp:ObjectDataSource ID="DataServiceSource" runat="server" 
    TypeName="CuttingEdge.Samples.FakeDataService"
    SelectMethod="GetOrdersByEmployee">
    <SelectParameters>
        <asp:ControlParameter Name="year" 
            ControlID="AvailableYears" PropertyName="SelectedValue" /> 
        <asp:ControlParameter Name="empid" 
            ControlID="EmployeeList" PropertyName="SelectedValue" /> 
    </SelectParameters>
</asp:ObjectDataSource>

업데이트 가능한 패널 내에서 다시 게시가 트리거되면 원래 컨트롤과 연결된 모든 서버 쪽 코드가 실행됩니다. 그러나 설명했듯이 다시 게시는 게시 단추의 특성과 관계없이 Atlas 대역 외 호출을 사용하여 전개됩니다. 부분 렌더링이 사용되는 경우 ScriptManager 컨트롤은 즉석에서 페이지의 태그를 수정하고 패널 새로 고침의 모든 잠재적인 트리거에 제출 스크립트 코드를 추가합니다. 잠재적인 트리거에는 패널의 모든 단추 컨트롤과 트리거로 등록된 모든 컨트롤이 포함됩니다. 이에 대해서는 잠시 후 설명하겠습니다.

또한 ScriptManager 컨트롤은 기본 ASP.NET 렌더링 프로세스에 연결되고 패널의 컨트롤을 위한 수정된 태그를 캡처합니다. 이후 태그는 대역 외 호출에 대한 응답으로 클라이언트에 전송됩니다.

사용자가 그림 5에서와 같은 제출 단추를 클릭하면 부분 다시 게시가 발생하고 코드 숨김의 Button1_Click 처리기가 실행됩니다.

Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)
    TimeServed.Text = "Served at " + DateTime.Now.ToString("hh:mm:ss")
End Sub

개체 데이터 소스에 바인딩된 표는 다시 게시가 수행되면 코드 없이 자동으로 새로 고쳐집니다. 수동 바인딩 폼을 선택한다면 다시 게시가 수행될 때 표를 해당 데이터에 바인딩하는 역할을 직접 처리해야 합니다.

표가 페이징 또는 정렬을 지원하는 경우 페이지나 정렬을 클릭할 때마다 패널 또한 새로 고쳐집니다. 패널 외부에서 발생하는 클릭은 모두 평소와 같이 ASP.NET에 의해 처리되며 전체 페이지 새로 고침을 유발합니다. 언급된 바와 같이 패널 업데이트의 트리거로 등록된 모든 컨트롤 및 이벤트는 이 규칙에 대한 예외입니다. Atlas 프로그래밍 모델의 이러한 측면으로 진행하기 전에 진행률 표시줄에 대한 기본 제공 지원에 대해 간단히 살펴보겠습니다.


페이지 맨 위로페이지 맨 위로

진행률 표시줄 추가

UpdatePanel 컨트롤을 Atlas 진행률 표시줄 컨트롤과 연결할 수 있습니다. 정확하게 말해 진행률 표시줄은 계기 구성 요소가 아니라 ScriptManager 컨트롤이 패널 새로 고침이 시작될 때 표시했다가 완료되면 즉시 감추는 사용자 정의 패널입니다. Atlas 진행률 표시줄 컨트롤은 UpdateProgress라고 합니다.

<atlas:UpdateProgress id="progress1" runat="server">
    <ProgressTemplate>
        <div>
            <img alt="" src="images/indicator.gif" />
            <span id="Msg">Please, wait ... </span>
        </div> 
    </ProgressTemplate>
</atlas:UpdateProgress>

여기에서 알 수 있듯이 UpdateProgress 컨트롤은 포함된 ProgressTemplate 속성을 통해 ASP.NET 태그를 렌더링합니다. 템플릿에는 텍스트, 움직이는 텍스트 및 애니메이션 이미지를 삽입할 수 있으며 삽입된 항목은 패널 새로 고침이 완료될 때까지 유지됩니다. 이를 위해 스크립트나 관리 코드는 전혀 필요치 않으며 간단히 Atlas Web Form에 UpdateProgress 컨트롤을 추가하기만 하면 됩니다. 그림 6은 예를 보여 줍니다.


그림 6 UpdateProgress 컨트롤
그림 6 UpdateProgress 컨트롤

예를 살펴보면 쿼리에 사용된 일부 매개 변수를 포함하도록 대기 메시지를 개인화하는 것이 가능하지 않을까 하는 의문이 생길 것입니다. 예를 들어 "Fuller님에 대한 데이터를 검색하는 동안 잠시 기다려 주십시오."와 같은 메시지를 표시하는 것이 가능할지 생각해 볼 수 있습니다. 진행률 컨트롤에서 서버 이벤트가 발생하는 시점은 클라이언트의 테스트를 업데이트하기에는 너무 늦습니다. 유일한 방법은 부분 다시 게시가 시작되기 전에 실행되는 약간의 JavaScript 코드를 클라이언트에 추가하는 것입니다. 그러나 Submit 클라이언트 이벤트는 이미 ScriptManager 컨트롤에 의해 연결되었으므로 게시 단추의 클라이언트 Click 이벤트는 캡처할 수 없습니다. 시도할 수 있는 한 가지 방법은 입력 컨트롤에서 클라이언트 Change 이벤트를 처리하는 것입니다. 예를 들어 그림 6의 EmployeeList 드롭다운 목록에 다음 특성을 추가할 수 있습니다.

onchange="UpdateMsg(this.options[this.selectedIndex].text);"

UpdateMsg 함수는 다음과 같이 작성할 수 있는 Javascript 함수입니다.

<script type="text/javascript">
    function UpdateMsg(empName)
    {
        var msg = document.getElementById("Msg");
        msg.innerHTML = "Please, wait while data for " + empName + 
                        " is retrieved ...";
    }
</script>

페이지 개체 모델을 사용하여 드롭다운 목록의 선택 변경에 따라 Msg span 태그의 텍스트를 수정할 수 있습니다. 표시하려는 텍스트에 영향을 주는 입력 필드가 변경될 때마다 JavaScript를 사용하여 프로그래밍 방식으로 진행률 패널을 업데이트합니다. 그림 7에서 결과를 볼 수 있습니다.

그림 7 진행률 컨트롤에서 사용자 지정 메시지 사용
그림 7 진행률 컨트롤에서 사용자 지정 메시지 사용 (크게 보려면 이미지를 클릭하십시오.)

UpdateProgress의 하위 컨트롤에 포함된 일부 특성만 프로그래밍 방식으로 설정하려는 경우에는 UpdateProgress 컨트롤에 대한 OnLoad 처리기를 정의하고 FindControl 메서드를 사용하여 템플릿에서 컨트롤을 검색하면 됩니다.

Sub progress1_OnLoad(ByVal sender As Object, ByVal e As EventArgs) _
        Handles progress1.Load
    DirectCast(progress1.FindControl("Msg"), Label).Text = "..."
End Sub

이 코드 역시 서버에서 실행되는 시점은 클라이언트의 진행률 모니터링 텍스트를 업데이트하기에는 너무 늦습니다.

그림 5의 코드를 다시 살펴보면 UpdatePanel 컨트롤과 UpdateProgress 컨트롤을 연결하는 요소가 전혀 없음을 알 수 있을 것입니다. 요점은 UpdateProgress 컨트롤 한 개로 페이지의 모든 UpdatePanel 컨트롤을 해결할 수 있다는 것입니다. Web Form에서 업데이트 진행률 컨트롤 한 개로 여러 개의 새로 고침 패널을 사용할 수 있습니다. Atlas 스크립트 관리자는 해당하는 고유한 업데이트 진행률이 각각의 새로 고침 패널을 처리하도록 관리합니다. 진행률 컨트롤이 여러 개인 경우에는 어떻게 될까요? 업데이트되는 패널에 관계없이 모든 진행률 컨트롤이 동시에 표시됩니다.


페이지 맨 위로페이지 맨 위로

트리거 추가

UpdatePanel 컨트롤을 사용한 Atlas 프로그래밍에 새로운 프로그래밍 모델이나 새로운 API가 필요한 것은 아닙니다. 그러나 패널 업데이트 메커니즘은 여기에서 살펴본 것보다 복잡합니다. 예를 들어 다음과 같이 패널에 트리거를 추가할 수 있습니다.

<atlas:UpdatePanel runat="server" ID="Panel1">
    <ContentTemplate> 
        ...
    </ContentTemplate>
    <Triggers>
        <atlas:ControlEventTrigger ControlID="Btn" EventName="Click" />
    </Triggers>
</atlas:UpdatePanel>

UpdatePanel 컨트롤의 Triggers 블록에 ControlEventTrigger의 인스턴스를 포함시킬 수 있습니다. 이벤트 트리거를 사용하면 지정된 컨트롤에서 지정된 이벤트가 발생할 경우 스크립트 관리자가 패널을 새로 고칩니다.

기본적으로 폼의 모든 업데이트 패널은 어떤 패널 컨트롤이 실제로 트리거를 정의했는지에 관계없이 페이지의 트리거가 동작하면 새로 고쳐집니다. 이러한 동작을 변경하여 자체 트리거가 동작할 때만 각 업데이트 패널이 새로 고쳐지도록 하려면 UpdatePanel 컨트롤의 Mode 특성을 Conditional로 변경해야 합니다.

<atlas:UpdatePanel ID="Panel1" Mode="Conditional" runat="server" ... />

타이머 컨트롤은 트리거 및 진행률 표시줄과 함께 사용할 수 있는 매우 흥미로운 Atlas 컨트롤입니다.

<atlas:TimerControl ID="timer1" runat="server" Interval="5000" 
    OnTick="timer1_Tick" />

위의 타이머 컨트롤은 5초마다 Tick 이벤트를 발생시킵니다. 타이머의 Tick 이벤트에 패널을 바인딩하면 업데이트 가능한 패널을 주기적으로 새로 고칠 수 있습니다.

<atlas:UpdatePanel runat="server" id="Panel1">
    <ContentTemplate>
       ...
    </ContentTemplate>
    <Triggers>
        <atlas:ControlEventTrigger ControlId="timer1" 
            EventName="Tick" />
    </Triggers>
</atlas:UpdatePanel>

주기적인 업데이트는 긴 작업이 실행되는 동안 사용자에게 상황에 맞는 피드백을 제공하기 위한 핵심입니다.


페이지 맨 위로페이지 맨 위로

상황에 맞는 피드백

상황에 맞는 사용자 피드백은 서버의 응답을 기다리는 동안 사용자에게 표시되는 상태 정보를 의미합니다. Atlas UpdateProgress 컨트롤을 통해 표시되는 정보와 달리 상황에 맞는 피드백에 맞게 설계된 인프라는 작업 진행 및 응답 생성에 따라 새로 고쳐지는 최신 정보를 제공합니다. 모니터링 대상 작업의 진행에 따라 앞으로 움직이는 전형적인 진행률 표시기를 생각하면 이해하기 쉽습니다. 지난달에는 작업을 시작하고, 이 작업이 상태 정보를 사용하여 서버 쪽 캐시를 업데이트하도록 하고, 현재 사용 가능한 상태 정보를 통해 주기적, 비동기적으로 새로 고쳐지는 UI를 만드는 단계에 따라 순수 ASP.NET 2.0 솔루션에 대해 설명했습니다.

이 모델을 Atlas로 이식할 때 처음 떠오르는 방식은 첫 번째 UpdatePanel을 작업에 사용하고, 필요에 따라 UpdateProgress 컨트롤에 삽입되는 두 번째 UpdatePanel을 사용하여 진행률 표시기를 구현하는 것입니다. 진행률 UpdatePanel은 타이머에 바인딩되고 적절한 속도로 업데이트됩니다.

이 논리적 모델은 UpdatePanel 및 ScriptManager 컨트롤의 내부 구현과 충돌합니다. Atlas는 대역 외 요청을 시작하기 위해 클라이언트 쪽 개체를 사용합니다. 이 개체는 Atlas 클라이언트 라이브러리에 속하는 PageRequestManager입니다. 요점은 이러한 개체 단 한 개로 페이지의 모든 UpdatePanel 컨트롤을 처리한다는 것입니다. 결과적으로 요청을 serialize해야 하며, 주 작업이 진행되는 동안에는 상태를 읽기 위한 동시 요청을 전송할 수 없게 됩니다. 그러나 Atlas는 자동으로 요청을 일괄 처리하여 하나의 그룹으로 서버에 전송할 수 있습니다.

Atlas에서 상황에 맞는 피드백을 구현하려면 수동 메커니즘을 구축하고 서버로 통하는 모든 호출을 완전하게 제어해야 합니다. 페이지는 JavaScript 타이머를 설정하고, 원격 작업을 시작하고, 상태 정보로 페이지를 업데이트하는 많은 양의 스크립트 코드를 포함하게 됩니다. 모니터링 대상 작업은 페이지 메서드를 통해 시작됩니다. 페이지 메서드는 상태 정보를 읽는 데도 사용됩니다.

<script type="text/VB" runat="server">
    <WebMethod()> _
    Public Function GetSalesEmployees(ByVal taskID As String, _
            ByVal year As Integer) As String
        Return GetSalesEmployeesInternal(taskID, year)
    End Function

    <WebMethod()>  _
    Public Function UpdateStatus(ByVal taskID As String) As String
        Return UpdateStatusInternal(taskID)
    End Function
</script>

단추를 클릭하면 GetSalesEmployees 메서드가 호출되며 이 메서드는 FakeDataService와 함께 작동하여 쿼리를 실행하고 데이터를 가져옵니다. 단추를 클릭할 때 실행되는 코드는 다음과 같습니다.

function StartTask()
{
    var years = document.getElementById("AvailableYears");
    var year = years.options[years.selectedIndex].value;
 
    EnableUI(false);
 
    globalTaskID = GetGuid();
    ShowProgress();
    PageMethods.GetSalesEmployees(globalTaskID, year, onTaskCompleted);
}

이 코드는 먼저 드롭다운에서 선택된 연도를 검색하고, 작업을 고유하게 식별하기 위한 GUID를 생성하고, 상태 정보를 읽기 위한 타이머를 가동한 다음 마지막으로 오래 걸릴 수 있는 작업을 시작합니다.

작업을 구현하는 코드와 상태를 읽는 코드는 사용할 API와 상태 정보를 읽고 쓰는 데 사용되는 저장 매체에 대해 일치해야 합니다. 이 예에서는 ASP.NET 캐시에서 작업 ID에 따라 이름이 지정된 슬롯에 상태 정보가 저장됩니다. 작업 ID는 클라이언트에 알려져야 하며 약간의 JavaScript를 사용하여 생성됩니다. 여러 세션이 충돌 없이 같은 페이지를 사용할 수 있게 하려면 작업 ID가 고유해야 합니다. 그림 8은 작업이 진행되는 동안 상태를 업데이트하는 데이터 서비스 메서드의 코드를 보여 줍니다.

JavaScript 타이머에서 제어하는, 주기적으로 실행되는 페이지 메서드 호출에 의해 상태 정보가 읽힙니다.

function ShowProgress()
{
    PageMethods.UpdateStatus(globalTaskID, onUpdateProgress);
    EnableStatusBar(true);
    timerID = window.setTimeout("ShowProgress()", 1000);
}
function StopProgress()
{
    window.clearTimeout(timerID);
    EnableStatusBar(false);
}

이전의 코드와 Atlas 타이머를 사용하는 다음 코드는 어떤 차이가 있을까요?

<atlas:TimerControl runat="server" ID="Timer1" Interval="1000" 
    OnTick="..." />

효과는 완전히 동일합니다. 즉, 매초 서버에서 하나의 서버 코드가 실행됩니다. 그러나 Atlas 타이머를 사용하는 경우에는 클라이언트 사용자 인터페이스를 활성화 또는 비활성화하는 등 대역 외 호출을 활용하는 추가 스크립트 코드를 지정할 수 없습니다.


페이지 맨 위로페이지 맨 위로

요약

ASP.NET Atlas는 비교적 쉽고 빠르게 풍부한 기능의 브라우저 불문 대화식 웹 사용자 인터페이스를 개발할 수 있도록 설계된 프레임워크입니다. Atlas 프로그래밍 모델을 기존 ASP.NET 모델의 단순한 확장으로 사용하여 간단하게 업그레이드할 수 있는 시나리오가 많이 있습니다. Atlas는 다양한 일반적인 상황을 위해 이미 갖추어진 훌륭한 도구를 제공합니다. 요구가 Atlas 도구 집합과 일치하는 경우에는 정교한 응용 프로그램을 신속하고 효과적으로 개발할 수 있으며 무엇보다 읽고 유지 관리하기 쉬운 코드를 작성할 수 있습니다.

Atlas는 표준 ASP.NET과 근접할 정도로 기능을 잘 수행하지만 더 높은 수준의 유연성을 원할수록 더 많은 JavaScript 코드를 작성하여 서버 코드에 통합해야 합니다. 이러한 작업은 때로 어려운 경우가 있습니다. Atlas 기반 프레임워크는 바로 이러한 상황을 위한 것입니다. Atlas는 몇 가지 뛰어난 기본 도구를 갖춘 하위 수준 프레임워크로 디자인되었습니다. 다른 상용 프레임워크에서는 보다 수직적인 도구 집합을 제공하며, 이러한 도구 집합에 포함된 기본 제공 구성 요소를 사용하면 기본적인 Atlas 기능 이상을 구현할 때 필요한 고급 클라이언트 및 서버 코드의 상당 부분을 작성할 필요가 없어집니다.


페이지 맨 위로페이지 맨 위로


Dino에게 질문이나 의견이 있으면 메일을 보내시기 바랍니다.  cutting@microsoft.com.

Dino EspositoDino Esposito는 Solid Quality Learning의 강사이며 Programming Microsoft ASP.NET 2.0(Microsoft Press, 2005)(영문)의 저자입니다. Dino는 이탈리아에서 거주하며 전 세계 산업 관련 행사에서 많은 활동을 펼치고 있습니다. cutting@microsoft.com으로 전자 메일을 보내거나 저자의 블로그 weblogs.asp.net/despos (영문)를 통해 연락하십시오.


페이지 맨 위로페이지 맨 위로QJ: 061011

Microsoft