기본 콘텐츠로 건너뛰기

간단한 mithril router 예제.

http://meteorpad.com/pad/fH4tQSizz8vskj3N5/mithril_router 일단 링크. Meteor.startup ->   Home =     controller: ->       onunload: ->         console.log "unloading home component"     view: -> [       m "div", "home"       m "a[href=/dashboard]", config: m.route, "to Dashboard"     ]   Dashboard =     controller: ->     view: -> [       m "div", "dashboard"       m "h1",         m "a[href=/]", config: m.route, "to home"     ]   m.route.mode = "pathname"   m.route document.body, "/",     "/": Home     "/dashboard": Dashboard 소스는  http://mithril.js.org/mithril.html 과  http://mithril.js.org/mithril.route.html  내용 참조. router 진입시 필요한 것들은 controller 에서 사용하면 되는데 unload시 처리는 onunload 을 return 값의 key로 사용하면 된다. view에서 a 링...

Template events 안에서 function 사용팁

Template events안에서 function을 쓸 때 global scope 으로 쓰는 게 싫으셨죠? var clickProcess = function(e) { ... }; Template.nono.events({ 'click .button': function(e, tmpl) { clickProcess(e); ... }, 'touchend .button': function(e, tmpl) { clickProcess(e); ... } }); 이렇게 쓰지 말고 Template.nono scope 안으로 가둡시다. Template.nono.clickProcess = function(e) { ... } 그러고 나서 event 안에선 tmpl.view.template 으로 참조하면 Template.nono 자신을 가져올 수 있습니다! Template.nono.events({ 'click .button': function(e, tmpl) { tmpl.view.template.clickProcess(e); ... }, 'touchend .button': function(e, tmpl) { tmpl.view.template.clickProcess(e); ... } }); 더 이상 글로벌 스코프로 인한 불안에 떨지마세요~

amok 에서 vim으로 coffeescript 를 사용하는 법

amok.js  는 아주 빠르고 멋진 코드 갱신을 할 수 있게 하는 작은 툴이다. webpack의 Hot module replacement 와는 차원이 다른 반응속도를 보여준다. 물론, 구조도 더 단순하고 무엇보다 러닝커브가 낮다. uglify 툴로 이전에 언급한 Tracker.js , mithril.min.js , MeteorDDP.js 를 모두 묶어서 util.js 라고 만들고 > uglify -s MeteorDDP.js,Tracker.js,mithril.min.js -o util.js html 파일은 간단하게 만들자 <!DOCTYPE html> <html lang="en"> <head>   <meta charset="UTF-8">   <title>Mamok</title> </head> <body> <script src="./util.js"></script> <script src="./index.js"></script> </body> </html> index.js 를 바라보게 했는데 사실은 index.coffee를 쓸거다. 'use strict' window.addEventListener 'patch', ->   m.redraw() m.module document.body,   view: -> [     m 'h1', 'Hey, Brother.'     m 'h3', m.trust '<button>hey hey</button>'   ] 아주 짧지만 신통한 구조다. 파일 변경을 감지하...

Tracker+DDP+Mithril=Success!

Mithril 을 좀 보고 있다. 무엇보다 가볍고 (12kb) 성능이 어마어마( http://matt-esch.github.io/mercury-perf/ )하고 디자인 사상도 매우 깔끔해서 마음에 들었다. 그래서 혹시 Meteor랑 같이 쓸 방법은 없을까 해서 뒤적거려 보았더니 http://lhorie.github.io/mithril-blog/mithril-and-meteor.html 아주 좋은 글이 있더라. Mithril을 Meteor에서 사용하면서 Reactivity를 구현하기 위해 Deps(현재는 Tracker)객체를 controller에 붙이고 unload 될때 computation을 멈추는 것까지 아주 깔끔하게 구현해 놓았다. 만든이가  https://github.com/meteor/meteor/wiki/Tracker-Manual  의 내용을 잘 숙지하고 있는 것 같다. React에서 getMetadata + Mixins를 사용하는 방법보다 더 납득이 가는 방식이었다. 그렇다면, 꼭 Meteor를 전부쓰지 않더라도 Mithril에서 Tracker package만 사용하고 DDP를 엮는 것만으로도 굉장히 가볍고 강력한 클라이언트쪽 Reactive Programming 구현을 할 수 있겠다 싶었다 DDP서버로만 Meteor를 사용해도 되고 PythonDDP, GoDDP 같은 것들이 있으니까 node.js를 사용하지 않아도 별 상관이 없다. 강력하다! GDG모임에서 React+Meteor Lightning Talk 발표를 하면서 조금 React를 공부해서 그런지 생각이 정리가 잘 되어서 쉽게 검증해볼 수 있었는데. 먼저 필요한 라이브러리들을 모아보았다. 1. Meteor Tracker Package https://github.com/meteor/meteor/tree/devel/packages/tracker 2. Meteor Javascript DDP (/w promise)  https://...

UI깎는 노인-Making a knob for Mobile

Knob, 흔히들 Dial 이라고 말하는 전통적인 인터페이스가 있다. 돌리고~돌리~고~ ( 출처 ) webAudio를 하다보니 (  http://jsbin.com/hacota ,  http://output.jsbin.com/tidoqi  등등) 직관적인 UI 컨트롤러가 필요해서 잠깐 찾다가 이럴게 아니라 최소한의 요소만 뽑아내서 만들어보기로 함. 목표는 PC/Android/iOS 모두 잘 작동하도록 하는 것. 구현할 기능을 생각해보면 현재 값을 시각화하는 요소가 있을 것 - 위 사진에서처럼 음각으로 만든 홈. 경계값이 있을 것 - 12시 방향 기준으로 -140도~140도까지 클릭 후 드래그 시만 움직이고 즉각적으로 반응 정도로 잡고 일단 SVG로 원을 두개 그려본다.       <circle cx="6em" cy="6em" r="5em"/>       <circle class="handle" cx="6em" cy="3em" r="0.6em"/> 단위는 서로 다른 디바이스에서도 잘 보이도록 em을 써서 만든다. 1em은 글자 한글자 높이정도의 단위인데 해상도에 대한 걱정을 덜어줘서 참 편하다. em은 이정도, 즉 1em=1글자 높이 이걸 돌려주기만 하면 된다. 돌리는 건 뭘로? css transform / rotate 를 사용한다. 두 개의 원을 그룹으로 묶어서 돌리자.     <g class="jog" style="-webkit-transform: rotate3d(0,0,1,{{knob}}deg); transform: rotate3d(0,0,1,{{knob}}deg)">       <circle cx="6em" cy="6em" r="5em...

REST없이 DDP로 외부 Meteor 서버 데이터 끌어오기

Meteor는 Web Application이지만 기존 HTTP 통신을 최초에 자원을 읽어올때 한번만 사용하고 그 이후로는 DDP(Distributed Data Protocol  https://www.meteor.com/ddp )를 이용하여 자료교환을 합니다. Meteor 작동방식( http://meteorhacks.com ) DDP를 Websocket을 위한 REST라고 이야기하기엔 결정적으로 다른 차이점 하나가 있다. HTTP의 경우는 요청(Request)을 하면 응답(Response)를 주는 방식으로 연결이 유지가 되지 않는 반면, DDP 는 기본적으로 Connection을 한번 맺으면 클라이언트와 계속 연결을 유지하면서 실시간 송수신을 주고 받는다. DDP는 WebSocket을 사용하고 SockJS를 사용하여 XMLHttpRequest 로 대체하기도 한다. 어떤 식으로 전송/수신을 하는지 Chrome의 Developer Tools를 통해 WebSockets 흐름을 한번 살펴보자. DDP Websocket 캡쳐화면 Meteor에서 클라이언트/서버간 통신하는 내용을 살펴보면 의외로 별게 없는데 Random.id()로 생성한 id값과 msg 종류. name 이름과 나머지 인자값들이 전부다. 클라이언트쪽에서 보면  1. 연결 요청(connect)한다. {   "msg":"connect",   "version":"pre2",   "support": ["pre2","pre1"] } 2. subscribe 한다. {   "msg":"sub",   "id":" j9jDEAyCxPnNELqGE ", /* 이 id로 ready를 받는다 */   "name":"...

pub/sub RethinkDB in Meteor

Meteor DevShop 영상 중 RethinkDB에 대한 언급이 있었는데 그냥 그런게 있구나하다가 최근에 데이터베이스에서 변경 고지쪽의 중요함을 피부로 느끼고 설치도 해보고 좀 살펴보았다. https://github.com/tuhinc/rethink-livedata  같은 구현도 있고 코드를 보니 꽤 좋아보였다. 일단, 기존의 Meteor가 어떻게 mongoDB의 변경을 감지하는지 알아볼 필요가 있는데 mongo 콘솔에서 데이터를 직접 조작하면 Meteor Application에서도 실시간으로 적용되는 모습은 처음 접하는 사람들에겐 대단히 흥미로운 부분이다. 이것이 가능한 이유는 mongoDB가 그 자체로 oplog라는 이름의 collection(정확히 말하면 capped collection이라고 고정용량인 환형 collection인데 자세한 설명은 http://docs.mongodb.org/manual/core/replica-set-oplog/  이쪽을 참조)을 가지고 있어서인데 Meteor가 이 oplog를 감시하면서 변경내역이 있을 때마다 DDP로 변경내용을 갱신하여 구현하였다. 이 oplog라는 collection은 local이라는 이름의 system database에 있고 아래와 같이 접근 가능하다. > use local > show collections me oplog.rs startup_log system.indexes system.replset > db['oplog.rs'] .find().pretty() .... { "ts" : Timestamp(1438072144, 1), "h" : NumberLong("-854779810064123573"), "v" : 2, "op" : "i",...