본문 바로가기

node.js (OctoberSkyJs)

[node.js 따라배우기 06] 인터페이스 기본 (Interface Basics)

이번 번역은 함께 Octoberskyjs 스터디를 진행하고 있는 김주회님(@ByJuhoi )께서 수고해 주셨습니다. : )

웹 앱(Web App)을 만들어 봅시다파트6에 오신걸 환영합니다. 본 시리즈는 Node를 사용하여 웹 앱을 만들어 보는 튜토리얼(tutorial)입니다. 이 시리즈는 자기만의 어플리케이션을 만들 때 직면하게 될 모든 부분들을 당신에게 알려줄 것입니다. 이 튜터리얼들은 lmawa 링크에 있습니다.

Part 1: 소개 (Introduction)

Part 2: 설치와 애플리케이션 뼈대 만들기 (Installation and Skeleton App)

Part 3: RESTful 메소드와 테스트 (RESTful Methods and Testing)

Part 4: 템플릿, 파셜, 그리고 문서 생성과 수정(Templates, Partials, Creating and Editing Documents)

Part 5: 인증과 세션, 접근제어 미들웨어 (Authentication, Sessions, Access Control Middleware)



컴퓨터 시작 시 mongo 데몬이 자동으로 실행되는 것이 아니라면 이 튜터리얼을 시작하기 전에 실행시키기 바랍니다.

우리는 이전 파트에서 인증과 세션에 대해서 살펴봤습니다. 특히 원활한 접근 제어를 만들기 위해 미들웨어라는 멋진 개념을 사용했습니다. 이번 주에는 jQuery를 사용하여 더욱 재미있는 인터페이스를 만드는 법을 설명할 것입니다.
 
인터페이스 디자인

저는 앱을 개발하기 전 인터페이스를 설계할 때 보통은 개략적인 아이디어로 계획을 세웁니다. 이것이 일반적으로 알려진 탑-다운 방식의 설계입니다. 우선 그 인터페이스가 작동할 것 같으면 그 다음에 간단한 인터페이스와 테스트에 대한 API를 개발합니다. 지금까지 우리가 이 튜토리얼 시리즈에서 해왔던 것처럼 말입니다.

저는 모눈종이와 샤프펜슬 그리고 좋은 지우개를 가지고 인터페이스에 대해 스케치하는 것을 좋아합니다. 제가 계속 개략적으로 스케치를 하다 보니 저의 동료들은 그것이 설계가 끝나지 않았다는 것을 알고 있습니다. 그 스케치는 우리가 그 프로젝트에 대해 토의하면서 발전하게 될 아이디어들입니다.



간략히 스케치한 Nodepad는 다음 사항들을 제시하고 있습니다. 

  • 인터페이스는 마치 데스크탑의 어플리케이션처럼 두 개의 패널이 있고 하나는 노트의 목록을, 다른 하나는 노트의 내용을 위해서 사용됩니다.
  • 저장 버튼이 하단에 있긴 하지만 자동-저장 기능이 더 좋을 것입니다.
  • 노트를 한번 클릭하면 내용을 읽어오고, 더블-클릭하면 제목을 수정할 수 있게 합니다.
  • 이메일과 비밀번호를 변경하기 위해서 계정설정(account setting)이 필요합니다.
  • 우리는 이미 JSON을 지원하기 때문에 편집할 때 XMLHttpRequest를 사용할 수 있습니다.
 

속임수(Cheating)

인터페이스를 설계할 때 가장 중요한 것 중 하나는 가능한 많이 속이는 것입니다. 저는 프로그래밍을 할 때 이미 잘 짜여진 라이브러리가 있는데 같은 기능을 구현하기 위한 코드를 작성하기 위해 시간을 소비하지 않습니다. 설계 또한 마찬가지라고 할 수 있습니다. 필요한 모든 아이콘을 그릴 필요는 없으며, 또한 레이아웃에도 쓸데없는 시간을 소비할 필요가 없습니다.

요즘은 CSS 프레임워크부터 Cappuccino 같은 무거운 GUI 프로젝트까지 사용 가능한 많은 솔루션들이 있습니다. 우리는 Nodepad를 만들기 위해 가장 많이 쓰이고 있는 jQuery UI를 사용할 것입니다. 그것은 견고한 테마와 결합했을 때 더 큰 효과가 있을 것입니다.

테마로는 Aristo (demo)를 사용하기로 결정했습니다. 그것이 꼭 최고의 테마라고는 할 수 없지만, 많이 사용해 봤고 꽤 괜찮아 보인다는 생각이 듭니다.


Aristo와 jQuery UI를 포함시키기

Github에서 Aristo를 다운로드하여 public/stylesheets/aristo 에 놓습니다. 그리고 나서 views/layout.jade 템플릿에서 jQuery UI와 새로운 stylesheet를 읽어오기만 하면 됩니다:

link(rel='stylesheet', href='/stylesheets/aristo/jquery-ui-1.8.5.custom.css')
script(type='text/javascript', src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js')
페이지 구조

우리의 인터페이스는 두 개의 컬럼과 헤더, 편집을 위한 문서의 몸통 부분 그리고 문서를 관리하기 위한 몇몇 버튼들이 필요합니다. Jade에서는 다음과 같습니다.

div(class='outline-view', id='left')
  div(id='DocumentTitles')
    ul(id='document-list')
      - for (var d in documents)
        li
          a(id='document-title-' + documents[d].id, href='/documents/' + documents[d].id)
            =documents[d].title

  ul(class='toolbar')
    li
      a(href='/documents/new')
        +
    li
      a(href='#', id='delete-document')
        -

div(class='content-divider')

div(class='content')
  div(id='editor-container')
    textarea(name='d[data]', id='editor')
      =d.data || ''

ul(id='controls',class='toolbar')
  li
    a(href='#', id='save-button') Save

처음 부분에서 outline-view는 문서의 목록을 포함하는 div입니다. 이것은 전에도 본 적이 있는 코드입니다. 이것들을 absolute로 위치시켰고 문서 목록과 버튼 툴바의 사이즈를 조절하기 위해서 resize와 focus라는 JavaScript를 사용합니다.

선택된 문서는 CSS gradient를 사용하여 보여줍니다.


브라우저가 CSS3 gradient를 지원하지 않아도 상관 없습니다. 다만 좀 어두운 색으로 보여줄 뿐 괜찮게 보일 것입니다.

.outline-view ul .selected {
  color: #fff;
  background-color: #8897ba;
  background: -webkit-gradient(linear, left top, left bottom, from(#b2bed7), to(#8897ba));
  background: -moz-linear-gradient(top,  #b2bed7,  #8897ba);
}

문서 선택하기

우리의 API는 JSON 데이터를 돌려 받기 위해 URL에 .json 을 추가하여 다시 호출합니다. 우리는 서버로부터 문서를 읽어오기 위해 몇몇의 간단한 jQuery 이벤트 핸들링만을 사용합니다.

$('#document-list li a').live('click', function(e) {
  var li = $(this);

  $.get(this.href + '.json', function(data) {
    $('#document-list .selected').removeClass('selected');
    li.addClass('selected');
    $('#editor').val(data.data);
    $('#editor').focus();
  });

  e.preventDefault();
});

이것은 문서 제목이 클릭 됐을 경우 실행하게 될 클릭 핸들러를 바인드한 것입니다. JSON 응답으로부터 받은 data 값이 txetarea에 채워집니다. 일반적인 이벤트에 비해서 live는 문서 목록이 변경되는 경우에 위임을 설정하기 위해 사용되곤 합니다.
 

문서 저장

저는 동적인 인터페이스를 만들 때 간단한 명명 규칙을 사용하여 데이터베이스 ID를 기반으로 id 속성을 설정하는 것을 좋아합니다. Nodepad에서는 DOM id를 다음과 같이 사용합니다: document-844ce17994ba1b87d359000001. 데이터베이스 ID를 찾으려면 쉽게 하이픈(-)으로 분할하여 마지막 부분을 가져오면 됩니다.

규칙이 정해지면 아주 소량의 jQuery 플러그인을 사용해서 아이템의 ID를 추출할 수 있습니다.


$.fn.itemID = function() {
  try {
    var items = $(this).attr('id').split('-');
    return items[items.length - 1];
  } catch (exception) {
    return null;
  }
};

이것은 저장 버튼이 눌렸을 때 아주 간단히 문서를 저장하게 합니다.

$('#save-button').click(function() {
  var id = $('#document-list .selected').itemID(),
      params = { d: { data: $('#editor').val(), id: id } };
  $.put('/documents/' + id + '.json', params, function(data) {
    // Saved, will return JSON
  });

사실상 jQuery에는 put에 대한 HTTP 동사가 없기 때문에 다음과 같이 정의했습니다.

$.put = function(url, data, success) {
  data._method = 'PUT';
  $.post(url, data, success, 'json');
};


진행사항

사실 지금까지 어떤 jQuery UI도 사용하지는 않았지만 다음 파트에서는 다루게 될 것입니다. 지금까지 우리는 좀 더 친숙하고 쓸만해 보이기 시작하는 간단하고 작은 에디터를 만들었습니다.
아직 브라우저 테스트 할 시간이 없어서 Webkit 이나 Firefox에만 충실했습니다.

Nodepad 최근 커밋은 dd40b 입니다.

업데이트: library, binary 그리고 운영체제에 대하여 테스트한 상세사항을 포함하여 Nodepad README를 변경했습니다. 이것은 문제가 발생하는 사람들에게 도움이 될 것입니다.