How Batman can Help you Build Apps ã®ç¿»è¨³
æè¿è©±é¡ï¼ã®CoffeeScriptãã¼ã¹ã®ãã¬ã¼ã ã¯ã¼ã¯Batman.jsã®HARRY BRUNDAGEï¼@harrybrundageï¼æ°ã«ããç´¹ä»è¨äºãHow Batman can Help you Build Appsãã翻訳ãã¾ããã
å
ã¨ã³ããªã¯これã§ãã
Batman.jsã¯Shopifyã«ããæ°ããCoffeeScriptã®ãã¬ã¼ã ã¯ã¼ã¯ã§ãéçºã«é·ãæéã®ããã£ãããã¤ãç´¹ä»ã§ããã®ã§æ¬å½ã«è奮ãã¦ãããBatman.jsã®GitHubã¯ここã ã
Batmanã¯å¤§ããªå½±é¿åãæã¤ç´ æ´ããããã¬ã¼ã ã¯ã¼ã¯ã«æºã¡ãä¸çã«ç¾ãããSproutcore 2.0ãBackbone.jsã¨ãã£ãé©ãã¹ãããã¸ã§ã¯ãã®ææãããä¸ã§ãéçºè
ã¯ã©ãããã¤ä½¿ããã©ããã£ã¦å¦ã¹ã°ããã®ã ããï¼ æ°ããã¦ãã£ããããã¼ã«ã§éãã§ããæéã¯éããã¦ããã®ã§ãããã§ã¯Batmanã¨ä»ã®ãã¬ã¼ã ã¯ã¼ã¯ã¨ã®éããããã³ä»ã®ãã¬ã¼ã ã¯ã¼ã¯ã®ãããã«Batmanã使ãçç±ãç°¡åã«è§£èª¬ãããã
Batmanã¯ã¢ããªéçºãç°¡åã«ãã
Batmanã¯ã·ã³ã°ã«ãã¼ã¸ã®ã¢ããªãéçºããããã®ãã¬ã¼ã ã¯ã¼ã¯ã ãProgressive EnhancementãDOMãAJAXãªã©ã®åä¸ç®çã®ã©ã¤ãã©ãªã§ã¯ãªãããã©ã¦ã¶éäºæããã¼ã¿è»¢éãããªãã¼ã·ã§ã³ãã«ã¹ã¿ã ã¤ãã³ãã¨ãã£ãéçºã®éå±ãªé¨åãå
¨ã¦å®è£
ãããã¨ã§ãæé«ã®ã·ã³ã°ã«ãã¼ã¸ã¢ããªãæ§ç¯ã§ããããã¼ãããéçºããããã®ã ãã³ã¼ããçæãå®è¡ããéçºç¨ã®ä½¿ãããããã«ãã¼ãã³ã¼ããæ´çãã¦å¿
è¦ã«å¿ãã¦å¼ã³åºãããã®ããããã¢ããªæ§é ããã«MVCã¹ã¿ãã¯ããã®ä»ããããã®ãã¼ã«ã18ãããã¤ãï¼gzipæ¸ã¿ï¼ã®ãµã¤ãºã§æä¾ãã¦ãããBatmanã¯åºæ¬çãªãã®ã ãæä¾ããããã§ããããã¨ãããããã®ãæä¾ããããã§ã¯ãªããèªåã®ã¢ããªã«å¿
è¦ãªã³ã¼ãããããæè»ãªAPIãæä¾ãã¦ããã
è¶
ä¸ç´ã®ã©ã³ã¿ã¤ã
Batmanã®å¿èé¨ã¯ã©ã³ã¿ã¤ã 層ã§ããªãã¸ã§ã¯ãã®ãã¼ã¿ã®æä½ã¨ãªãã¸ã§ã¯ããçºçãããã¤ãã³ãã¸ã®ç»é²ã«ä½¿ããã¦ãããBatmanã®ãªãã¸ã§ã¯ãã¯SproutCoreãBackboneã®ãã®ã¨ä¼¼ã¦ãã¦ãBarmanãªãã¸ã§ã¯ãã®ããããã£ã«å¯¾ããã¢ã¯ã»ã¹ã¨ä»£å
¥ã¯ãç´ ã®JavaScriptã®ãããè¨æ³ã§ã¯ãªãsomeObject.getã¨someObject.setã使ããªããã°ãªããªãããããå®ããã¨ã§ã以ä¸ã®ãããªå©ç¹ãããã
- ãæ·±ããããããã£ãåç´åã§ãè¨ç®åã§ãééçã«ã¢ã¯ã»ã¹ã§ãã
- ããããã£ãã§ã¼ã³ä¸ã®ãªãã¸ã§ã¯ãã®è¨ç®åã®ããããã£ãç¶æ¿ã§ãã
- ãæ·±ãããã¹ã®ä¸ã®ä»ã®ãªãã¸ã§ã¯ãã®changeãreadyã¨ãã£ãã¤ãã³ãã«ç»é²ã§ãã
- ãªã«ããéè¦ãªã®ã¯ããããã£éã®ä¾åé¢ä¿ã追跡ã§ããã®ã§ãé£éãããªãã¶ã¼ããçºåãããè¨ç®çµæãææ°ã§ãããã¨ãä¿è¨¼ãã¤ã¤ãã£ãã·ã¥ã§ãããã¨ã
ãã®æ©è½ã¯ãã¹ã¦ã®Batmanãªãã¸ã§ã¯ãå©ç¨ã§ãããããç´ ã®JavaScriptã¨ãã¦ãæ±ããã¨ãã§ãããã©ã³ã¿ã¤ã ã§ã§ãããã¨ãå°ã試ãã¦ã¿ããããªãã¸ã§ã¯ãã®ããããã£ã¯Batman.Object::observeã使ã£ã¦ç£è¦ã§ããã
crimeReport = new Batman.Object crimeReport.observe 'address', (newValue) -> if DangerTracker.isDangerous(newValue) crimeReport.get('currentTeam').warnOfDanger()
ä¼¼ãæ©è½ã¯BackboneãSproutCoreã«ãããããBatmanã«æ°ãã«åãå ¥ãããã®ããæ·±ãããã¼ãã¹ã ãBatmanã§ã¯ãããã§ã¤ãªãããã¨ã§ãªãã¸ã§ã¯ãã®é£éã追跡ã§ããã
batWatch = Batman currentCrimeReport: Batman address: Batman number: "123" street: "Easy St" city: "Gotham" batWatch.get 'currentCrimeReport.address.number' #=> "123" batWatch.set 'currentCrimeReport.address.number', "461A" batWatch.get 'currentCrimeReport.address.number' #=> "461A"
ãªãã¶ã¼ãã®æå®æã«ã使ããã
batWatch.observe 'currentCrimeReport.address.street', (newStreet, oldStreet) -> if DistanceCalculator.travelTime(newStreet, oldStreet) > 100000 BatMobile.bringTo(batWatch.get('currentLocation'))
ä¸çªã¯ã¬ã¤ã¸ã¼ãªã®ã¯ãããã®ãªãã¶ã¼ãã¯ãã®ãã¼ãã¹ããªãã§ããï¼ãã¨ããã¼ãã¹ã®éä¸ãå¤åãã¦ãï¼ããã®å¤ã§çºåãããã¨ã ã
crimeReportA = Batman address: Batman number: "123" street: "Easy St" city: "Gotham" crimeReportB = Batman address: Batman number: "72" street: "Jolly Ln" city: "Gotham" batWatch = new Batman.Object({currentCrimeReport: crimeReportA}) batWatch.get('currentCrimeReport.address.street') #=> "East St" batWatch.observe 'currentCrimeReport.address.street', (newStreet) -> MuggingWatcher.checkStreet(newStreet) batWatch.set('currentCrimeReport', crimeReportB) # ä¸è¨ã®"MuggingWatcher"ã®ã³ã¼ã«ããã¯ããJolly Lnãã§å¼ã°ãã
ä½ãèµ·ããããåããã ãããããã¼ãã¹ã®éä¸é¨ãå¤åãã¦ããªãã¶ã¼ãã¯æ°ãããæ·±ããå¤ã§çºåããããã®æ©è½ã¯ä»»æã®é·ãã®ãã¼ãã¹ã§ããundefinedãå«ãã ãã¼ãã¹ã§ãåä½ããã
ããã²ã¨ã¤ã®ã©ã³ã¿ã¤ã ã®ããã¨ããã¯ããã¹ã¦ã®ã¢ã¯ã»ã¹ãgetã¨setãéãã¦è¡ãããã®ã§ãè¨ç®ãå¿ è¦ãªããããã£éã®ä¾åé¢ä¿ã追跡ã§ãããã¨ã ãBatmanã§ã¯ããããé¢æ°ãã¢ã¯ã»ãµã¨å¼ã¶ãã¢ã¯ã»ãµã¯ãCoffeeScriptã®å®è¡å¯è½ãªã¯ã©ã¹ã使ã£ã¦ç°¡åã«å®ç¾©ã§ããã
class BatWatch extends Batman.Object # BatWatchã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã®ãcurrentDestinationããã¼ã®ã¢ã¯ã»ãµãå®ç¾©ãã @accessor 'currentDestination', -> address = @get 'currentCrimeReport.address' return "#{address.get('number')} #{address.get('street')}, #{address.get('city')}" crimeReport = Batman address: Batman number: "123" street "Easy St" city: "Gotham" watch = new BatWatch(currentCrimeReport: crimeReport) watch.get('currentDestination') #=> "123 Easy St, Gotham"
éè¦ãªã®ã¯ãããã§è¨ç®åã®ããããã£ã«ç»é²ãããªãã¶ã¼ãã¯ä¾åé¢ä¿ãæ´æ°ããããã³ã«çºåãããã¨ã ã
watch.observe 'currentDestination', (newDestination) -> console.log newDestination crimeReport.set('address.number', "124") # "124 Easy St, Gotham"ãã³ã³ã½ã¼ã«ã«åºåããã
ããã©ã«ãã®ã¢ã¯ã»ãµãå®ç¾©ãã¦ããã°ããã®ãã¼ãã¹ã§ã®ã¢ã¯ã»ãµãå®ç¾©ããã¦ããªãã¦ããã©ã³ã¿ã¤ã ããã©ã¼ã«ããã¯ãã¦ãããã
jokerSimulator = new Batman.Object jokerSimulator.accessor (key) -> "#{key.toUpperCase()}, HA HA HA!" jokerSimulator.get("why so serious") #=> "WHY SO SERIOUS, HA HA HA!"
ãã®æ©è½ã¯ãªãã¸ã§ã¯ãã«åºæ¬ã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ãä¸ãããã¨ãã«æç¨ã ããèªæã§ã¯ãªãæ¹æ³ã§ãã¼ã¿ã¨é£åãããã¨ã«ãªããä¾ãã°Batman.Hashã¯ã¤ãã³ããçºè¡ããªãã¸ã§ã¯ãããã¼ã¨ãã¦ä½¿ããããã«ããä¸ã§ãæ¨æºçãªJavaScriptã®ãªãã¸ã§ã¯ãã¨é¡ä¼¼ããAPIãæä¾ããããã«ãã®æ©è½ã使ã£ã¦ããã
ä½ã«ä½¿ããã®ã?
ä¸è¨ã§è§£èª¬ããBatmanã®ã³ã¢ã¯ããã¼ã¿ã®å¤æ´ããã£ãã¨ãå³åº§ã«ãããç¥ããã¨ãå¯è½ã«ãããã¯ã©ã¤ã¢ã³ããµã¤ãã®ãã¥ã¼ãªã©ã«ã¯æé©ã ããã¥ã¼ã¯ããã¯ãé·å¤§ãªæååã¨ãã¦åºãããã¯ã©ã¤ã¢ã³ãã«éä¿¡ãããéçãªHTML群ã§ã¯ãªãããã¥ã¼ã¯ããã¼ã¿ã«ãããã£ã¦å¤åããé·å¯¿å½ã®ãã¼ã¿è¡¨ç¾å½¢å¼ã ãBatmanã®ãã¥ã¼ã·ã¹ãã ã¯ããããã£ã®è½åãå¼·åããã
Alfredï¼Batmanã®ToDoã¢ããªãµã³ãã«ï¼ç¨ã®ãã¥ã¼ã®ç°¡æçã以ä¸ã ã
<h1>Alfred</h1> <ul id="items"> <li data-foreach-todo="Todo.all" data-mixin="animation"> <input type="checkbox" data-bind="todo.isDone" data-event-change="todo.save" /> <label data-bind="todo.body" data-addclass-done="todo.isDone" data-mixin="editable"></label> <a data-event-click="todo.destroy">delete</a> </li> <li><span data-bind="Todo.all.length"></span> <span data-bind="'item' | pluralize Todo.all.length"></span></li> </ul> <form data-formfor-todo="controllers.todos.emptyTodo" data-event-submit="controllers.todos.create"> <input class="new-item" placeholder="add a todo item" data-bind="todo.body" /> </form>
ãã©ã³ã¹ãã¤ã©å±¤ãããããï¼HAMLãªãï¼ããã³ãã¬ã¼ã層ããããããï¼Ecoãjadeãmustacheããªãï¼ãBatmanã®ãã¥ã¼ã·ã¹ãã ã¯HTML5ã§ããã¦ã³ãã¼ããããã®å ´ã§ãã©ã¦ã¶ãã¬ã³ããªã³ã°ãããJavaScriptæååã§ã¯ãªãããªãããªDOMããªã¼ã§ãBatmanã解æãã¦ãã¼ã¿ãåãè¾¼ããã³ã³ãã¤ã«ãæååå¦çã¯è¡ããªããç´ æ´ããããã¨ã«Batmanã¯ãã¼ãã®å¤ãã©ã³ã¿ã¤ã ã§ç£è¦ãããã¨ã§ããã¤ã³ãããããJavaScriptã®ä¸çã§å¤ãå¤åããã¨ããã¤ã³ãããã対å¿ãããã¼ãã®å±æ§ã¯èªåçã«æ´æ°ãããã¦ã¼ã¶ã¯ãã®å¤åãè¦ããéãã¾ãçã§ãããã¹ããã£ã¼ã«ãã«å ¥åãããããã§ãã¯ããã¯ã¹ãã¯ãªãã¯ãããããã¨ãæååãçå½å¤ãJavaScriptã®ãã¤ã³ãããããªãã¸ã§ã¯ãã«ã»ããããããCocoaãããã¯JavaScriptãªãKnockoutãSproutcoreã«ããããã«ãã¤ã³ãã®æ¦å¿µã¯æ°ãããã®ã§ã¯ãªãã
ãã¤ã³ããé¸æããã®ã¯ a)æåã§ãã¼ã¿ã®å¤æ´ããã§ãã¯ããããªã b)ãã¼ã¿ããããå¤ãã£ããããã§ãã³ãã¬ã¼ãå ¨ä½ãåæç»ããããªã ããã ãMustacheãjQuery.tmplã«é¡ããã·ã¹ãã ã§ã¯ããã©ããã»ã©é »ç¹ã«ãã®ä¸¡æ¹ãããç¾½ç®ã«ãªã£ãããã£ãã²ã¨ã¤ã®ãã¼ããæ´æ°ãããã¦ããã²ã¨ã¤ã®è¦ç´ ã®ã²ã¨ã¤ã®ãã¼ãå¤æ´ããã ãã§ãã«ã¼ãå ã§å ¨è¦ç´ ãåæç»ããããããã®ãã¼ã追å ã®ããã«ãã£ãæ¯æãã®ã¯æéã®ç¡é§ã«æãããSproutCoreã®SC.TemplateViewãYehuda Katzã®ä½ã£ãHandlebars.jsã¯ããããå´åãæ¸ããã«ã¯ããã§ãã¦ãããããã¯ããã©ã¦ã¶ã®ä¸ã§å ¨ã¦ã®æååæ¼ç®ãããããã¯ãªãã®ã§ããã¥ã¼ã®å ¨ãã¼ã¿ãå³å¯ã«ããããã£ã«ãã¤ã³ãããå¤ç§çãªç²¾å¯ãã®æ¹ãé¸æããã
ãã¥ã¼ã®é常ã¬ãã«ã®è¤éãã®ãã¸ãã¯ã¨ã²ãããã«ããã¼ãä¸ç»é¢ã®ãããªãé«éãªæç»ãæå¾ã«ã¯æã«å ¥ãããBatmanã®ãã¥ã¼ã¨ã³ã¸ã³ã«ã¯ãæ¡ä»¶åå²ãã«ã¼ããã³ã³ãã¯ã¹ããç°¡åãªå¤æãªã©ãããããã³ã¼ããæ¸ããã¨ã¯ã§ããªããBatmanã§ã¯å¯¾è©±ç¨ã®è¤éãªã³ã¼ãã¯Batman.Viewã®ãµãã¯ã©ã¹ã«è¨è¿°ããªããã°ãªãããHTMLã¬ã³ããªã³ã°ã¯ããããã£ã¨ãå¾æãããã®ã«ãããããããªãã¡ãã©ã¦ã¶ã«ã
ãã£ã¨ç¥ããã?
Batmanã¯ãã®æ´è½ãæ·±ããã¼ãã¹ã®æ©è½ãå¥å¦ãªããã³ãã¬ã¼ããããªãHTMLãã®ä»ã«ããããããªãã¨ãã§ãããæ¬ä¼¼ãã¼ã¸éãªã³ã¯ã®ããã®ã«ã¼ãã£ã³ã°ãããï¼GETã®ãã©ã¡ã¼ã¿ã¾ãã¯ã»ã°ã¡ã³ã対å¿ï¼ãBatman.Model層ã¯ãã¼ã¿ã®å¦çãéä¿¡ãè¡ããRailsãlocalStorageã®ãããªã¹ãã¬ã¼ã¸ããã¯ã¨ã³ãã§ããã«ä½¿ãããBatman.StateMachineãBatman.EventEmitterã¯ãªãã¸ã§ã¯ãã«mixinãã¦ä½¿ããä»ã«ããããããããWebサイトãGitHubにあるソースã[irc://freenode.net/batmanjs:title=freenodeã®#batmanjs]ãªã©ããã§ãã¯ãããã¨ãå¼·ãããããããã質åããã£ã¼ãããã¯ãããããªã©ã¯å¤§æè¿ã ããBatmanãã©ãæ¹åããããããã®ææ¡ã¯ãã¤ã§ãåãå
¥ããã