최근에 프로젝트에 ExtJS를 비록하여 몇가지 JavaScript 프레임워크를 검토한 적이 있다.
내부적으로 ExtJS를 사용하고 있지만, 결코 주변의 다른 프로젝트를 진행하고 있는 사람들에게는 적극적으로 권하지 않는다. 왜냐하면, 한국은 HTML, CCS 그리고 JavaScript를 웹 프로그램의 한 부분으로 생각하지 않고 있을 뿐더러, 그렇다고 디자이너의 역할 중의 하나라고도 생각하지 않는다. 그렇게 때문에 HTML, CSS 그리고 JavaScript의 전문가를 찾아 보기가 쉽지 않다.

ExtJS를 권하지 않는 이유는 처음 이를 사용할 때는 Windows에서나 제공할 수 있었던 많은 기능들이 컴포넌트화 되어 있어서, 사용하기 편할거라는 생각을 하는데, 이를 응용한 새로운 컴포넌트를 만들거나 제대로 기능을 사용하려면, 약 2달정도의 학습시간이 필요하기 때문이다. 개발 초기에 이를 감안한다면, 사용하는 것은 별 문제 없지만, 기존의 HTML과 CSS만을 이용할 때보다는 전체 개발시간이 늘어날 거라고 반드시 예상하고 개발 플랜을 잡아야 할 것이다.

최근에 기존에 개발되어 있던 기능을 살펴볼 일이 있었다.
개발자가 ExtJS의 코드를 그대로 가져다 써서 인지 사소한 버그가 있었다. ExtJS의 버그나 잘못은 아니라고 생각한다. Ajax와 ExtJS의 그리드 컴포넌트를 이용하였는데, 마지막 페이지에 있던 Rows를 모두 삭제하면 이전 페이지로 이동해야 하는데, 마지막 페이지 그대로를 표시하는 것이었다.

그래서, 몇가지 자료를 찾아보았더니, 관련된 예제는 아래와 같은 Link에 있었다.
그리드에 데이터 목록을 가져오고, 목록에 추가/수정/삭제에 대한 예제가 있다.

예제: Tutorial:Using Ext grid form dialog to achieve paging list, create, edit, delete function 

이중에서 delete에 대한 예제는 아래와 같았다. (아래 Delete Function 예제 참조)

 Delete function

Delete function will get the selected id(s) and create JSON data and send JSON data to Java server-side for handle.

/************************************************************
    * Action - delete
    *   start to handle delete function
    *   need confirm to delete
    ************************************************************/	
    function doDel(){
        var m = grid.getSelections();
        if(m.length > 0)
        {
        	Ext.MessageBox.confirm('Message', 'Do you really want to delete it?' , doDel2);	
        }
        else
        {
        	Ext.MessageBox.alert('Message', 'Please select at least one item to delete');
        }
    }     
 
    function doDel2(btn)
	{
       if(btn == 'yes')
       {	
			var m = grid.getSelections();
			var jsonData = "[";
	        for(var i = 0, len = m.length; i < len; i++){        		
				var ss = "{\"id\":\"" + m[i].get("id") + "\"}";
				//alert(ss);
				if(i==0)
	           		jsonData = jsonData + ss ;
			   	else
					jsonData = jsonData + "," + ss;	
				ds.remove(m[i]);								
	        }	
			jsonData = jsonData + "]";
			ds.load({params:{start:0, limit:myPageSize, delData:jsonData}});		
		}
	}

And delete parameter to server side with JSON data like this: delData=[{"id":"5"},{"id":"6"}]


위 예제를 보면, 서버로 데이터를 요청할 때, 파라메터로 start 값과 limit값을 보내줌을 알수 있다.
상기 예제 소수의 하단을 보면,    ds.load({params:{start:0, limit:myPageSize, delData:jsonData}});
라는 코드가 눈에 들어올 것이다. 이를 이용하여, 서버에서 DB에 쿼리를 수행해서 현재 페이지에서 필요로 하는 첫 번째 인텐스 값과 현재 페이지에서 표시할 수 있는 데이터의 갯수를 가져오는 것인데, 위 예제는 기본적으로 "0"번 인덱스를 서버로 보내서 매번 1페이지만 가져오는 것이다.

만약 이를 해결하려면, 두가지 방법이 있는데

첫번째는 위에서 사용했던 함수 ds.load({params:{start:0, limit:myPageSize, delData:jsonData}});
의 start 파라메터에 이전 페이지의 첫번째 인덱스를 넣어주는 것이다. 이를 위해서는 전체 Total Counter를 이용하여 총 페이지 수와 인덱스를 찾는 로직이 필요한데, 이미 많이 사용되는 코드라 쉽게 찾고, 만들수 있을 거라 생각된다.

두번째는 페이지 네이션을 모두 서버에서 담당하는 것이다. 이 경우는 동시에 사용자들이 수정 추가 삭제에 대해 부분도 충분히 고려되어 질 수 있다. 이에 필요한 계산 로직은 위의 첫번째 방법과 별로 다르지는 않고 단지 책임에 대한 부분만 책임을 지면된다. 이때는 서버에 현재 페이지의 첫번째 인덱스 번호를 서버로 보내주는 것이 바람직하다.
이를 이용하여 서버에서는 전제 개수와 페이지를 계산하고 마지막 페이지가 존재하지 않는 경우 이전 페이지의 목록을 보내주면 되기 때문이다.
 

Posted by 행복상자
Pro Javascript를 전체적으로 한번 흩어 보고나서는, Javascript에 대한 이해도가 무척 높아졌다. 물론 당연히 알아야 할 것들을 그동안 모르는 채 잘 지내왔을 뿐이다.
내가 알던 쉬운 자바스크립트는 지금의 것과는 너무도 많이 달랐다. 아니 자바스크립트의 가능성과 기능에 대해서 너무 간과해 왔는지도 모른다.

HTML의 DOM 구조는 개발자로 하여금 문서의 구조을 쉽게 이해할 수 있도록 도와주고, 이는 CSS와
Javascript를 통해서 쉽게 제어할 수 있어 매우 유용하다.

<html>
<head>
<title>Introduction to the DOM</title>
<script>
    // We can't manipulate the DOM until the document
    // is fully loaded
    window.onload = function(){
    // Find all the <li> elements, to attach the event handlers to them
    var li = document.getElementsByTagName("li");
    for ( var i = 0; i < li.length; i++ ) {
        // Attach a mouseover event handler to the <li> element,
        // which changes the <li>s background to blue.
        li[i].onmouseover = function() {
            this.style.backgroundColor = 'blue';
        };

        // Attach a mouseout event handler to the <li> element
        // which changes the <li>s background back to its default white
        li[i].onmouseout = function() {
            this.style.backgroundColor = 'white';
        };
    }
};
</script>
</head>
<body>
<h1>Introduction to the DOM</h1>
<p class="test">There are a number of reasons why the
DOM is awesome, here are some:</p>
<ul>
    <li id="everywhere">It can be found everywhere.</li>
    <li class="test">It's easy to use.</li>
    <li class="test">It can help you to find what you want, really quickly.</li>
</ul>
</body>
</html>

위의 코드는 "Pro Javascript"에 나오는 예제인데, HTML은 XML의 구조를 가지고 있지만, 가장 단순한 형태중에 하나로 문서를 구성하는 Object를 정의하고 있다. 이러한 구조는 "태그(Tag)"라는 형태로 정의되어지는데, 위 예제는 태그에 Event의 handler를 할당하는 코드이다.

코드에 대한 설명을 덧 붙이자면,
1. var li = document.getElementsByTagName("li");
    - 위 코드를 통해서 HTML 문서에 정의된 "li" 태그들의 리스트를 가져와서 var li에 저장한다.
    - document.getElementsByTagName 메소드는 태그 이름을 이용하여 Element를 가져오는
      함수이다.

2. li[i].onmouseover = function() {this.style.backgroundColor = 'blue'; );
   - 위 코드를 정의하기 전에, "li.length"를 통해서 리스트의 갯수를 알수 있고 이를 For 루프 문의
     통해서 반복을 시킨다.
   - 이는 동일한 이벤트를 "li"태그로 정의된 Object에 할당하기 위새서이다.
   - li[i].onmouserover 이벤트 메소드는 위와 같이 새로 정의된 메소드를 통해서 마우스가 "li"태그
     위에서 움직일 때 태그의 배경색을 "blue"로 바꾸어 준다.

3. li[i].onmouseout = function() {this.style.backgroundColor = 'white'; };
    - 이 코드는 "li" 태그의 onmouseout event 메소드를 정의하는 코드로, 마우스가 태그를 벗어날때
      태그의 배경색을 "white"로 바뀌게 만들어 준다.

위의 코드를 이해할 수 있으면, jQuery에서 얼마나 직관적으로 같은 코드를 간략하고 단순한 형태로 사용할 수 있는지 알게된다면, 깊은 인상을 받을 것이다.
Posted by 행복상자
원래는 책에서 Closure에 대한 설명에 대한 설명이 있는데, 나의 관심을 끈 것은 Anonymous함수의 사용에 대한 것이었다.

아래의 예제는 동일한 동작을 하는 메소드를 Event에 추가하는 예제인데, 중간 정도에 보면 난데 없이 "(function(){" 으로 시작하는 구문이 나온다. 이 부분이 Anonymoun function 이다.
이렇게 만들면 "Global"로 선언할 필요없이 임시적으로 함수 블럭의 사용이 가능하다.
구문을 닫을 경우는 "})();"를 이용하면 된다.

 // An element with an ID of main
var obj = document.getElementById("main");

// An array of items to bind to
var items = [ "click", "keypress" ];

// Iterate through each of the items
for ( var i = 0; i < items.length; i++ ) {
    // Use a self-executed anonymous function to induce scope
    (function(){
        // Remember the value within this scope
        var item = items[i];
        // Bind a function to the elment
        obj[ "on" + item ] = function() {
            // item refers to a parent variable that has been successfully
            // scoped within the context of this for loop
            alert( "Thanks for your " + item );
        };
    })();
}

사실 위의 코드는 불필요한 내용들이 많이 들어있다. 굳지 저렇게 써야하나 라는 생각이 들지도 모르지만, 이것은 단지 예제 정도록 사용하면 된다.
그래도 몇가지 건질 것이 있다면, 위의 코드에서 "id"를 이용하여 오브젝트를 가져오고, Event를 Bind하는 내용을 담고 있는데, Event명을 obj["on" + item]의 형태로 Event를 binding한다.
위의 코드는 "click" 과 "keypress"에 대한 이벤트가 발생하면 메시지를 발생시키는 예제이다.

Posted by 행복상자

어떤 사람들은 믿지 않겠지만, Javascript도 Object Oriented Programming을 지원하는 Language이다. 이전에 자바 스크립트가 출현하 지난 10년동안 언어적인 측면과 사용적인 측면에서 많은 변화가 있었지만, 실제로 개발자들은 굉장히 소극적으로 이를 사용했었다. 따라서 별도의 Javascript 함수들을 모은 ".js" 파일을 이용하기도 했지만, 이는 단지 함수들을 재 사용하는 측명에서 였다. 이유는 코드를 고치거나 수정하기 어렵다는 것인데, 자바 스크립트가 가지고 있는 기본적인 속성들을 몰라서 일지도 모른다.
많은 사람들이 Javascript를 다시 보기된 계기는 Google의 Application들이 이를 이용해서 사람들에 자신들의 Application을 제공하기 시작했기 때문이라 생각하는데, 이어서 나온 Yahoo의 YUI도 내게 많은 놀라움을 주었다. 그리고 다른 오픈 소스 라이브러리들 역시 놀라운 정도의 편리함과 쉬운 사용법을 내세우고 개발자들의 쉴 틈(?)을 만들어 주고 있다.

그러나, 남의 것을 사용할 때도, 기본적이고 기초적인 것은 알아야 덜 고생한다.
세상에는 날로 먹을 만한 것이 그리 많지 않다.

오늘은 내가 잘 이해하지 못했던 Javascript의 Scope에 대해 설명할 거다.

자바스크립트는 기본적으로 웹브라우져의 페이지별로 실행된다. 그래서 대부분이 함수를 만들어서 그안에서 지역 변수를 생성하거나, 전역으로 생성해서 사용한다.
일반적으로 사용할때는 별 문제가 없겠지만, Java, C#, C/C++과는 Scope의 영향범위가 다르므로 주의해야 한다.

아래는 셈플 코드인데, 전역으로 foo 변수를 생성했고, 이어서 if 문안에 생성했고, 마지막으로
 function 문 안에서 생성하였다.

위에 주석으로 설명이 다 되어있지만, 다시 설명을 하면
6번째 줄에서 foo변수를 전역으로 선언하고 "test"라는 문자열을 저장하였다. 그리고 나서 12번째 줄에 새로운 foo 변수를 정의하고 "new test"라는 문자열을 저장하였다. 그러나 이는 이전에 생성했던 전경 변수와 동일하다. 다시 말하면, 이는 전역 Scope의 영향 아래에 있다. Java나 C#, C/C++은 전혀 다르므로 혹시 이를 착각하고 사용할 가능성이 많다.
이의 확인은 15번째 줄에서 알수 있다. 이를 실행하면 동일함을 확인할 수 있다.

이어서, 17번째에 함수 test를 만들고 24번째 줄에서 실행하면, 이전에 function test에서 할당한 문자는 function Scope에서 이미 생명주기가 다했음을 알수있다.

그럼다면, 함수안에 if 문에서 변수 foo를 새로 정의한 경우는 어떻게 될까?

한번 실행보면 알겠지만, 역시 if구문 안에 정의한 변수는 주의해야 한다. 자신이 원치 않는 결과를 가져올수 있다.
Posted by 행복상자
그 동안 관심은 있었으나, 제대로 마음먹고 해보지 못했던 자바 스크립트를 공부하기 시작한지 오늘로서 1주일이 다 되어 간다. 아니 사실은 5일정도 되었는데, 언어적인 측면에서는 그 동안 내가 익혔던 언어와 많이 다르다는 것을 깨닫고 있는 중이다. 

내가 공부하는 것을 정리하려고 하는데, 오늘은 Javascritp의 데이터 타입을 확인하는 방법에 대해서 간략하게 이야기 하려고 한다.

자바 스크립트에서 Type를 확인하는 방법은 2가지가 있다.
아래의 이에 대한 2가지 소스를 통해서 사용하는 방법에 대해 설명하려고 한다.

    // Check to see if our number is actually a string
    if ( typeof num == "string" )
    // If it is, then parse a number out of it

    num = parseInt( num );
    // Check to see if our array is actually a string

    if ( typeof arr == "string" )
    // If that's the case, make an array, splitting on commas

    arr = arr.split(",");

위의 예제에서는 Javascript에서 string 과 string type의 배열에 대해서,
- String 변수를 값이 저장된 경우는 number type의 변수에 저장하고,
- 만약 string 배열로 저장된 값일  경우는 이를 "," 를 구분자로 해서 배열로 저장한다. 
이 경우는 typeof 연산자를 이용해서 변수의 type을 확인하는 예제이다.
별로 이해하기 어려운 코드가 아니므로, 쉽게 이해할 수 있을 것이다.

두번째 방법은 먼저 아래의 예제를 보면, 이해가 쉡게 될 것이다.
    // Check to see if our number is actually a string
    if ( num.constructor == String )
    // If it is, then parse a number out of it
    num = parseInt( num );
    // Check to see if our string is actually an array
    if ( str.constructor == Array )
    // If that's the case, make a string by joining the array using commas
    str = str.join(',');


위 예제의 내용은 첫번째 예제와 코드의 결과물을 다르지 않다. 다만 여기서는 변수의 "construgtor"를 이용하여 "String"타입의 변수와 "Array"변수의 타입을 비교를 수행한 것이다.

물론 위와 아래의 예제 모두 실제 코드가 경우에, 필요에 따라 적절하게 사용하면 된다. 
아래의 표는 typeofconstructor를 사용이 가능한 Variable 목록들이다.


자바스크립트는 그리 많지 않은 변수들을 가지고 있다.
Posted by 행복상자
Ruby On Rails 환경 구성

요즈음 내가 갑자기 다양한 웹 기술에 관심을 갖게 되었다.  처음 웹을 접한지 벌써 10년이 넘어섰다. 그동안 큰 변화들이 있었지만 최근 1~2년의 기술 발전은 정말 비약적이다. 하루 하루 새로운 것이 나온다. 특히 ExtJS는 요즘 나의 관심거리이다. 현재 2.0 beta가 나온 상태이다.

그 동안 사용했던 웹 개발 환경도 참 다양하기도 하지...
아는 사람을 아는 Interdev 1.0 beta 버전을 이용하여 1996년 처음 ASP를 접했었다.
그리고 Perl을 이용해서 리눅스 환경에서 CGI를 개발하기도 했고, C컴파일러를 이용하여 HTML을 직접 제어하기도 했다. 그리고 현재는 Java를 이용하여 솔루션을 개발하고 있다.

그러나 이 모든것은 Server Side의 변화와 개발이었으며, 사용하는 언어는 개발 환경에 개발 속도에 영향을 주는 환경이었다. 어떤 개발 환경을 선택하냐에 따라 개발 결과와 효율이 크게 달라 졌었다. 사실, Vi 에디터는 웹 개발에는 별로 도움이 되지 않는 도구라고 생각할 때가 많았었다. (오해하지 마시라, Vi를 손발처럼 다루는 선수들 말고, 나를 예를 드는 것이니까... ^^) Web 서버와 DB서버를 오가면서 수동으로 작업할때 중간에 버리는 짜투리 시간들이 참 많다.특히 EJB로 개발할 때는 컨테이너 올리고 내리는 것은 정말 참기 어려운 작업이었다. 좀더 자동화 되고 지능적인 툴을 사용한다면, 시간을 생산해 낼 수 있다.

현재는 개인적으로 Roby를 공부 중인데,  아래는 집에서 사용하고 있는 개인용 PC에 설치되어 있는 gem 목록이다. 최근에 Rails를 설치하고 RedRails 플러그인을 eclipse에 설치해서 개발 환경을 만들었다. 그리고  DB는 학습을 위해서 간단한 Sqlite를 설치했다.

RedRails를 이용하여 예제를 생성하고, 테스트 하는 것은 정말 간단한 작업이었다. 그러나, 환경을 만들어 주는 것은 쉽지는 안았다. 시행 착오를 격으면서 gem 을 이용하여 Ruby 라이브러리를 설치하고 Eclipse 플러그인을 설치했다. 최신 버전을 설치하기 위해서는 검색엔진의 도움을 받는 것이 쉬운 길인듯 하다.

설치과정을 간단하게 설명하면(정말 간단하게),
 
1. Ruby 1.86 버전을 설치한다.
2. Eclipse 3.3 버전을 설치한다.
   - Ruby 개발을 위해, DLTK를 SW Update를 이용하여 설치한다.
3. Rails를 설치한다.
    - gem install rails 라고 도스 명령창에 입력후 앤터 (Y/N 확인을 해야 한다.)
   - 다음과 같이 Dependency 옵셜을 주면 자동으로 설치한다.
       gem install rails --include-dependencies
4. Eclipse를 위한 aptana 플러그인을 설치(
http://www.aptana.com)
   - aptana 사이트에서, RedRails 플러그인을 Eclipse에 설치한다.

이클립스에서 Rails 프로젝트를 만들어서 사요하면 되는데, 이는 다음을 참조한다.
동영상:
http://www.aptana.tv/movies/aptana_radrails_intro/aptana_radrails_intro.html

만약, 위 동영상 예제와 같이 sqlite를 이용하고 싶다면, sqlite를 다운받아야 하는데, 내가 약간의 시행 착오를 겪은 것은 sqlite.dll을 어디에 두어야 하는 것이지 였다. 
이 파일은 Rails가 만들어준 디렉토리중 bin 디렉토리에 두고 사용하면 된다.
아마 쉽게 위 동영상 예제를 따라 할 수 있을 것이다.

오늘 회사에서 Rails를 설치하려 했는데, 사내 보안 정책으로 인해서, gem을 사용할 수 없다는 것을 깨닫는데, 많은 시간이 걸렸다. 일종의 Proxy 정책의 영향인데, robyforge에 정상적으로 연결이 되지 않는다. Gem을 이용하여 Rails를 원격으로 설치할 수 없었다.

그래서 집에 있는 PC에 저장되어 있는 Gem 파일을 이용하여 Local에서 설치하려고 한다. 아래는 내 PC에 있는 gem 패키지 목록들이다.

도스창에서 dir/s *.gem 명령을 입력하고 실행시키면 된다.

사용자 삽입 이미지

Rails 설치를 위한 gem 파일 목록

Posted by 행복상자