2013. 10. 8. 18:30

아작스의 기원은 특정영역만 갱신하는 것이기 때문에 아작스영역안에서 포스백이 일어나면 '부분 포스트백'이라고 부릅니다.

당연히 페이지 포스트백은 일어나지 않을 것이라고 생각했습니다.

그런데 아니네요 ㅡ,.ㅡ;

(참고 : MSDN Magazine - AJAX 응용 프로그램 아키텍처, 1부 )

 

1. 문제 발견하기

아작스영역안에 버튼을 넣고 눌러 봅시다.

중단점을 잡아보면 페이지 로드에서 중단점이 잡힙니다.

 

 

신기하게도 페이지의 UI는 갱신이 되지 않네요 ㅡ.ㅡ;;

 

이 이야기는 업데이트페널이 각자 돌아간다고 생각하고 있는 우리의 상식을 벗어납니다.

 

 

1-1. 테스트용 코드

테스트를 위해서 '웹응용프로그램'프로젝트를 생성하고 웹폼을 추가 합니다.

 

그리고 아래 코드를 넣습니다.

 

<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        
        <br />
        페이지<br />
        <asp:Label id="labPage" runat="server" Text="Label" />
        <asp:Button ID="btnPage" runat="server" Text="페이지" OnClick="btnPage_Click"  />
        <br />
        <br />
        Ajax1
        <br />
        <asp:UpdatePanel ID="upAjax1" runat="server" OnLoad="upAjax1_Load" >
            <ContentTemplate>
                <asp:Label id="labAjax1" runat="server" Text="Label" />
                <asp:Button ID="btnAjax1" runat="server" Text="아작스1" OnClick="btnAjax1_Click" />
            </ContentTemplate>
        </asp:UpdatePanel>
        <br />
        <br />
        Ajax2
        <br />
        <asp:UpdatePanel ID="upAjax2" runat="server" OnLoad="upAjax2_Load">
            <ContentTemplate>
                <asp:Label id="labAjax2" runat="server" Text="Label" />
                <asp:Button ID="btnAjax2" runat="server" Text="아작스1" OnClick="Button1_Click" />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>

 

 

 

비하인드는 다음과 같이 작성합니다.

 

private readonly string m_sPage_Load = "PageCount";
private readonly string m_sPage_Button = "PageButton";

private readonly string m_sAjax1_Count = "Ajax1Count";
private readonly string m_sAjax1_Button = "Ajax1Button";

private readonly string m_sAjax2_Count = "Ajax2Count";
private readonly string m_sAjax2_Button = "Ajax2Button";

protected void Page_Load(object sender, EventArgs e)
{
	Session[m_sPage_Load] = Convert.ToInt32(Session[m_sPage_Load]) + 1;
			
	PageCountView();
}

protected void btnPage_Click(object sender, EventArgs e)
{
	Session[m_sPage_Button] = Convert.ToInt32(Session[m_sPage_Button]) + 1;

	PageCountView();
}

private void PageCountView()
{
	labPage.Text = string.Format("로드:{0}, 버튼:{1}"
									, Session[m_sPage_Load]
									, Session[m_sPage_Button]);
}
		
		



//Ajax1◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇

protected void upAjax1_Load(object sender, EventArgs e)
{
	Session[m_sAjax1_Count] = Convert.ToInt32(Session[m_sAjax1_Count]) + 1;

	Ajax1CountView();
}

protected void btnAjax1_Click(object sender, EventArgs e)
{
	Session[m_sAjax1_Button] = Convert.ToInt32(Session[m_sAjax1_Button]) + 1;

	Ajax1CountView();
}

private void Ajax1CountView()
{
	labAjax1.Text = string.Format("로드:{0}, 버튼:{1}"
									, Session[m_sAjax1_Count]
									, Session[m_sAjax1_Button]);
}


//Ajax2◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇◇

protected void upAjax2_Load(object sender, EventArgs e)
{
	Session[m_sAjax2_Count] = Convert.ToInt32(Session[m_sAjax2_Count]) + 1;

	Ajax2CountView();
}

protected void Button1_Click(object sender, EventArgs e)
{
	Session[m_sAjax2_Button] = Convert.ToInt32(Session[m_sAjax2_Button]) + 1;

	Ajax2CountView();
}

private void Ajax2CountView()
{
	labAjax2.Text = string.Format("로드:{0}, 버튼:{1}"
									, Session[m_sAjax2_Count]
									, Session[m_sAjax2_Button]);
}

 

 

 

 

 

 

 

1-2. 두번째 테스트

그래서 업데이트 페널을 2개 만들고 각각의 페이지에 버튼을 넣습니다.

(Asp.Net Ajax의 장점은 디자인코드에 몇가지만 추가하면 쉽게 Ajax를 사용 할 수 있다는 점입니다.)

 

위와같이 만들고 각각 아작스 버튼을 눌러 봅시다.

 

 

어라?

우리의 예상과 다르게 모든 아작스페이지가 갱신되고 있습니다.

거기다 위에서 말했던 것과 같이 메인페이지도 갱신되고 있죠.

 

이것은 MSDN Magazine의 글을 보면  이야기가 나옵니다.

 

viewstate와 다른 모든 숨겨진 필드가 수행되어 요청과 함께 서버로 업로드됩니다. 데이터를 받을 때는 업데이트된 viewstate와 함께 새로운 숨겨진 필드가 다운로드되며(있는 경우) 태그는 줄어드는 경우가 많습니다. 구체적으로 말하면 응답에는 포스트백 중에 수정된 업데이트 가능 영역의 태그만 포함됩니다. 목록에는 포스트백을 트리거한 UpdatePanel 컨트롤(및 중첩된 모든 패널), 페이지에서 UpdateMode 속성이 Always로 설정된 다른 모든 UpdatePanel 컨트롤, 프로그래밍 방식으로 새로 고친 모든 UpdatePanel 컨트롤이 포함됩니다. 다음 코드는 런타임 조건에 따라 프로그래밍 방식으로 패널을 새로 고치는 방법을 보여 주는 예입니다.

 

(원문 : MSDN Magazine - AJAX 응용 프로그램 아키텍처, 1부 )

 

특별한 설정을 하지 않는 경우 한페이지 안에 모든 업데이트 패널이 같이 갱신 된다는 의미 입니다.

 

 

2. 문제 해결

일반적으로 업데이트 패널은 자신이 갱신될 타이밍이 다른 업데이트 패널들과 다릅니다.

그러니 다른 패널의 포스트백은 피해야 하죠.

 

 

2-1. 'UpdateMode'를 이용

이럴때 쓰는 것이 'Update Mode' 속성입니다.

'Update Mode' 속성이 'Conditional'이면 다른 포스트백에 영향을 받지 않습니다.

 

 

이렇게 속성을 추가하고 테스트 해봅시다.

 

 

원하는 대로 따로 따로 노는 군요 ㅎㅎ

 

 

2-2. 'ChildrenAsTriggers'의 활용

 

때로는 내용물이 포스트백을 일으켜도 화면갱신은 할필요가 없을 때가 있습니다.

이럴때는 'ChildrenAsTriggers'속성을 사용합니다.

 

 

이제 테스트를 헤보겠습니다.

 

 

 

 

3. 주의 사항

위에서도 이미 말했지만 화면 갱신이 되지 않을 뿐이지 포스트백은 일어나고 있습니다.

이것은 다른 업데이트패널들도 마찬가지 입니다.

 

그렇기 때문에 페이지를 갱신하면 플러스된 값들이 한번에 갱신되는 것을 볼 수 있죠.

물론 'IsPostBack'같은 속성을 이용하여 포스트백을 걸러 낼수 있습니다.