MooJoe 0.9.0 릴리즈

얼마 전 강규영 님은 JavaScript 객체와 DOM Element를 맵핑시켜주는 JOE공개하셨습니다. JOE는 DOM Element를 모델 스토리지로 사용할 수 있게 해주는 굉장히 유용한 프로젝트입니다.

하지만 아쉽게도 jQuery 기반으로 만들어져 MooTools 1.2를 사용하는 VLAAH나 개인 작업에는 사용할 수 없었죠. 저는 곧 바로 JOE를 MooTools 스타일로 포팅하는 MooJoe 프로젝트를 시작했는데 한참 잊고 있다가 이제서야 공개합니다.


Simple Mapping

다음과 같은 HTML 코드가 주어졌습니다.

<div id="names">
    <p class="name">
        <span class="first">Heungsub</span>
        <span class="last">Lee</span>
    </p>
    <p class="name">
        <span class="first">Alan</span>
        <span class="last">Kang</span>
    </p>
</div>

척 보기에도 서버 측에서 두 개의 Name 객체를 div#names에 출력한 모습입니다. MooJoe는 JOE와 마찬가지로 DOM Element를 JavaScript 객체에 동기화시켜줍니다. 동기화를 하기 위해 먼저 Name 클래스를 정의합니다.

var Name = new MooJoe.Class({
    first: '.first',
    last: '.last'
});

MooJoe의 클래스는 MooJoe.Class 생성자로 만들 수 있습니다. 인자로 맵핑 룰을 지정할 수 있는데 Name 클래스의 경우 first 속성에 .first라는 CSS 셀렉터를, last 속성에 .last라는 CSS 셀렉터를 지정했습니다. CSS 셀렉터를 맵핑룰로 쓰기 때문에 .last가 항상 두 번째 span이라면 다음과 같이 써도 무관합니다.

var Name = new MooJoe.Class({
    first: 'span.first',
    last: 'span:nth-child(2)'
});

이제 div#names의 내용을 방금 만든 Name 클래스의 인스턴스로 만들어봅시다.

var names = [
    $$('#names p.name')[0].toObject(Name),
    $$('#names p.name')[1].toObject(Name)
];
// [name_instance#1, name_instance#2]

MooJoe는 MooTools의 Element 클래스를 확장해 Element.prototype.toObject 메서드를 제공합니다. 이 메서드에 맵핑시킬 MooJoe 클래스를 넘기면 맵핑된 객체를 반환합니다. 물론 다른 MooTools의 Element 메서드처럼 Elements.prototype.toObject로 짧게 쓰는 것도 가능합니다. 다음 코드는 방금 전 예제와 동일합니다.

var names = $$('#names p.name').toObject(Name);

맵핑시킨 속성들에 접근해볼까요? getter/setter는 MooTools 1.2의 컨벤션을 따릅니다.

names[0].get('first');
// 'Heungsub'
names[0].get('last');
// 'Lee'

names[0].set('first', 'Haesam');
names[0].get('first');
// 'Haesam'

또한 속성 값을 변경할 경우 맵핑된 Dom Element에도 즉각 반영됩니다.

...
    <p class="name">
        <span class="first">Alan</span>
        <span class="last">Kang</span>
    </p>
...

이 Element는

$$('#names p.name .first')[1].get('html')
// 'Alan'

names[1].set('first', 'Sungryong');

$$('#names p.name .first')[1].get('html')
// 'Sungryong'

이렇게 변합니다.

...
    <p class="name">
        <span class="first">Sungryong</span>
        <span class="last">Kang</span>
    </p>
...

여기까지는 단순히 자식 Element의 내용으로 속성을 맵핑시키는 간단한 사용법이었습니다. 하지만 속성이 항상 자식 Element에 표현되지만은 않겠죠. 가령 이름과 홈페이지 주소를 표현하는 경우를 생각해볼 수 있습니다.

<a class="person" href="http://heungsub.net/">이흥섭</a>

a.person으로부터 namehomepage 속성을 갖는 Person 객체를 만들고싶습니다. 어떻게 해야할까요?

Complex Mapping

MooJoe는 복잡한 맵핑룰을 제공합니다. 위 a.person을 객체로 만들기 위해 먼저 Person 클래스를 정의합니다.

var Person = new MooJoe.Class({
    name: ['', 'text'],
    homepage: ['', 'href']
});

맵핑룰에 CSS 셀렉터 대신 배열이 쓰였습니다. 이 경우 name 속성은 “이 Element의 text 값”에 맵핑시키고 homepage 속성은 “이 Element의 href 값”에 맵핑시킨다는 뜻입니다. 배열의 첫 번째 원소인 빈 문자열이 바로 “이 Element”를 가리킵니다. texthref는 MooTools의 getter/setter로 접근 가능한 키워드로, 각각 innerHTMLhref Attribute를 의미합니다.

var hs = $$('a.person')[0].toObject(Person);
// person_instance#1

hs.get('name');
// '이흥섭'
hs.get('homepage');
// 'http://heungsub.net/'

조금 더 복잡한 Person 예제를 볼까요?

<div class="person">
    <p class="face">
        <img src="http://farm4.static.flickr.com/3122/2894552409_3439382280_s.jpg" />
    </p>
    <p class="name">
        <a href="http://heungsub.net/">
            <span class="first">Heungsub</span>
            <span class="last">Lee</span>
        </a>
    </p>
    <p class="age">18</p>
</div>

이제 Person은 이름과 홈페이지 주소 뿐 아니라 사진, 나이, 게다가 Name 객체까지 표현해야합니다. 다행히 MooJoe으로 맵핑한 각 값을 특정한 타입이나 클래스로 캐스팅해줄 수 있습니다. Person 클래스를 다시 정의해봅시다.

var Person = new MooJoe.Class({
    name: ['.name a', Name],
    homepage: ['.name a', 'href', String],
    face: ['.face img', 'src', String],
    age: ['.age', Number]
});

homepageface의 룰은 3개의 원소로 되어있습니다. 각각 맵핑할 Element, 맵핑할 Attribute, 타입(클래스)을 나타냅니다. 맵핑할 Element인 첫 번째 원소를 제외하고는 순서가 바뀌어도 상관 없으며 기본값으로 각각 'text'String을 갖기 때문에 다음과 같이 써도 동일합니다.

...
    homepage: ['.name a', String, 'href'],
    face: ['.face img', 'src'],
...

name의 캐스팅 클래스는 Simple Mapping 예제에서 정의해뒀던 Name 클래스입니다. 자 그럼 객체로 구워볼까요?

var hs = $$('.person')[0].toObject(Person);

hs.get('name');
// name_instance#3
hs.get('name').get('first');
// 'Heungsub'

hs.get('face');
// 'http://farm4.static.flickr.com/3122/2894552409_3439382280_s.jpg'

hs.get('age');
// 18

name 속성은 Name 객체로, face는 문자열로, age는 숫자로 잘 캐스팅되는군요.

참 쉽죠?
(강규영 님 블로그에서 보고 너무 재미있어서 퍼왔습니다)

Detached Object

MooJoe 클래스를 MooTools 클래스처럼 사용할 수도 있습니다. 임의의 Name 객체를 만들어보겠습니다.

var new_name = new Name('Dachimawa', 'Lee');
new_name.attached;
// []

new_name.get('first');
// 'Dachimawa'
new_name.get('last');
// 'Lee'

생성자에 보낼 인자 순서는 맵핑룰 순서와 동일합니다. first 속성이 첫 번째 룰이었으므로 'Dachimawa'first 값이 됩니다.

attach() 메서드로 연결되어있지 않은 MooJoe 객체는 언제라도 Dom Element에 동기화시킬 수 있습니다.

...
    <p class="name">
        <span class="first">Sungryong</span>
        <span class="last">Kang</span>
    </p>
...

다음과 같이.

new_name.attach($$('.name')[1]);
new_name.attached;
// [<p.name>]

동기화시키는 순간 Dom Element의 내용도 업데이트됩니다. 원래의 내용이 MooJoe 객체의 내용으로 덮어씌워집니다.

...
    <p class="name">
        <span class="first">Dachimawa</span>
        <span class="last">Lee</span>
    </p>
...

다시 뗄 때는 detach() 메서드를 사용합니다.

new_name.detach();
new_name.attached;
// []

MooJoe 0.9.0은 다음과 같이 체크아웃 받을 수 있습니다.

svn checkout http://moojoe.googlecode.com/svn/tags/0.9.0 MooJoe

개발버전을 받고싶으시면 다음을 사용해주세요.

svn checkout http://moojoe.googlecode.com/svn/trunk MooJoe

버그 리포트 및 기능 제안은 프로젝트 이슈 페이지에서 해주세요.

아직 버그가 있긴 하지만 앞으로 차근차근 발전시켜나가야겠습니다. 특히나 MooJoe 프로젝트는 저의 첫 개인프로젝트이니만큼 애정을 갖고 말이죠. 그럼 0.9.1 버전 릴리즈 소식도 기대해주세요!

Tags: , , , ,

33 Responses to “MooJoe 0.9.0 릴리즈”

  1. sub's me2DAY says:

    이흥섭의 알림…

    드디어 MooJoe 0.9.0 릴리즈!…

  2. [...] 귀찮아서 그냥 그러고 있었다. 그런데 마침 후배 이흥섭이 나 대신 MooJoe라는 것을 만들어줬다. (사실은 내가 만드라고 막 시켰음… [...]

  3. 강규영 says:

    우왕ㅋ국 좋아요 ㅋㅋ

  4. cuthbertpa says:

    windows issues values against app joint seeding

  5. leanndacos says:

    president attributed working disputed depend 2007

  6. ellenaburg says:

    level growth stabilization observational

  7. jillesavel says:

    uncertainty reviews seeding gases

  8. freelandmo says:

    areas mitigating states google industrial

  9. דירות יוקרה…

    דירות יוקרה…

  10. اليورو …

    اليورو …

  11. dusteesava says:

    york weather dimming specific

  12. steelemont says:

    state alone investigate announced back rate

  13. croslyeaso says:

    agree microblogging down scaled land

  14. nanbrenn says:

    production frequency glacier costs america

  15. conyredmo says:

    million glacial indicate yahoo increases place others

  16. اسعار العملات…

    اسعار العملات…

  17. kimbroughp says:

    biological open net near page relates

  18. מתקני תצוגה…

    מתקני תצוגה…

  19. faegancalt says:

    increasing vectors southern fall output

  20. Eyqfznww says:

    comment3

  21. Ylatdeng says:

    comment2

  22. Aguljapn says:

    comment5

  23. Uvickizs says:

    comment1

  24. Rcgvcfty says:

    comment6

  25. Iutlyyko says:

    comment2

  26. Ydsrsvdj says:

    comment2

  27. Xhhvdljm says:

    comment5

  28. Ymwmmgql says:

    comment4

  29. Bgygqhhq says:

    comment2

  30. Rgltshhc says:

    comment2

  31. Mhltmnen says:

    comment4

  32. Fsmmgjpa says:

    comment3

  33. Ygqxrohi says:

    comment1

Leave a Reply