
ãã®æçš¿ã¯ã
ããããå§ãŸã£ãã·ãªãŒãºã®ç¶ã
ã§ã ïŒåã®éšåãèªãå¿
èŠããããŸãïŒã 仿¥ã¯ããããããto-doãªã¹ããïŒ
TodoMVCãããžã§ã¯ãã®Todoãªã¹ãïŒãäœæããŸãã
Angularã§
äœæãããããŒãžã§ã³ã«åºã¥ããŠã
ããŒããŒã§æ©èœãåäœæããŠãã ããã
äœæ¥ãªãã·ã§ã³ã調ã¹ã
ããã§ã¯ãAngularããŒãžã§ã³ã®å
容ãšãã®ä»çµã¿ãèŠãŠã¿ãŸãããïŒæ©èœãçè§£ããããã«5åããããŸãïŒã
- æ°ããã¿ã¹ã¯ãäžéšã®å
¥åãã£ãŒã«ãã«å
¥åããã
enter
ããŒãæŒããšãªã¹ãã«ç§»åããŸãã - ãªã¹ãå
ã®ã¿ã¹ã¯ã¯ãã¿ã¹ã¯ã®å³åŽã«ãããååããã¯ãªãã¯ããŠåé€ã§ããŸãïŒã¿ã¹ã¯ã«ã«ãŒãœã«ãåããããšè¡šç€ºãããŸãïŒã
- ã¿ã¹ã¯ã®å·ŠåŽã«ããããã§ãã¯ããŒã¯ããã¯ãªãã¯ããŠãã¿ã¹ã¯ããå®äºããšããŒã¯ã§ããŸãïŒãã§ãã¯ããã¯ã¹ããªãã«ããããšãã§ããŸãïŒã
- ã¿ã¹ã¯ãããã«ã¯ãªãã¯ãããšãç·šéã¢ãŒãã«ãªããå³ãEnterããŒãæŒããŸã-ã¿ã¹ã¯ãæŽæ°ãããŸãã
- ã¿ã¹ã¯ãå®äºããå Žåãå³äžã«ãå®äºå®äºããã¿ã³ã衚瀺ãããã¯ãªãã¯ãããšãå®äºããã¿ã¹ã¯ãåé€ãããŸãã
- å®äºããã¢ã¯ãã£ããªã¿ã¹ã¯ãã«ãŠã³ãïŒããã³è¡šç€ºïŒããŸãã ã¹ããŒã¿ã¹ããŒã®äžéšã
- ãŸããäžã®ã¹ããŒã¿ã¹è¡ã«ã¯3ã€ã®ãªã³ã¯ïŒãã¹ãŠãã¢ã¯ãã£ããå®äºãURLããããããïŒ/ãããïŒ/ã¢ã¯ãã£ããããïŒ/å®äºãã«å€æŽïŒããããããããã¯ãªãã¯ãããšã¿ã¹ã¯ãã£ã«ã¿ãŒã倿ŽãããŸãïŒãã¹ãŠã衚瀺ãããŸãã¢ã¯ãã£ããªã¿ã¹ã¯ïŒå®äºããŠããªãïŒãŸãã¯å®äºããã¿ã¹ã¯ã
åºç€ãšãªããã®
ïŒããè¯ãderbyjsãåŠç¿ããããã®ïŒç®æšã«åºã¥ããŠãããã§ã¹ã¿ã€ã«ãèãåºãããšã¯ããŸãããã¹ã¿ã€ã«ã¯ãã§ã«èšè¿°ãããŠãããã»ãšãã©ã®TodoMVCå®è£
ã§å€æŽãªãã§äœ¿çšãããŸãã
cssãã¡ã€ã«ãååŸã
ãŸã ã ããã
ãã£ãšèŠãŠã¿ããšãèæ¯
bg.pngã®åçãæ®ãå¿
èŠãããããšã
ããããŸãã ãŸããangularã«ãã£ãŠçæãããhtmlããã¬ãŒã ã¯ãŒã¯ãšããŠäœ¿çšããŸãïŒãã©ãŠã¶ãŒã®éçºè
ããŒã«ã䜿çšããŠã³ããŒããAngularãã£ã¬ã¯ãã£ãããå°ãåé€ããŸããïŒã
åºæ¬çãªhtmlã³ãŒã <section id="todoapp"> <header id="header"> <h1>todos</h1> <form id="todo-form"> <input id="new-todo" placeholder="What needs to be done?" autofocus> </form> </header> <section id="main"> <input id="toggle-all" type="checkbox"> <label for="toggle-all">Mark all as complete</label> <ul id="todo-list"> <li> <div class="view"> <input class="toggle" type="checkbox"> <label>hello</label> <button class="destroy"> </button> </div> <form > <input class="edit"> </form> </li> </ul> </section> <footer id="footer"> <span id="todo-count"><strong>0</strong> <span>items left</span> </span> <ul id="filters"> <li><a href="/" class="selected">All</a></li> <li><a href="/active">Active</a></li> <li><a href="/completed">Completed</a></li> </ul> <button id="clear-completed">Clear completed (0)</button> </footer> </section>
ã芧ã®ãšããããã®htmlã¯3ã€ã®ã¡ã€ã³ãããã¯ã§æ§æãããŠããŸãã
- ããããŒ-ãããã¡ã€ã³å
¥åã§ãã æ°ããã¿ã¹ã¯ãå°å
¥ããããã«å¿
èŠã§ãã
- main-ã¡ã€ã³ãããã¯ãã¿ã¹ã¯ãªã¹ãèªäœã¯ããã«æ ŒçŽãããŸãã
- ããã¿ãŒ-ã¹ããŒã¿ã¹è¡ãããã®æ
å ±ããã£ã«ã¿ãŒãšãã¯ãªã¢å®äºããã¿ã³ã®åãæ¿ã
ãããžã§ã¯ãæ§é
ããã§ã¯ãçç±ãèããŸãããã ç§ãã¡ã®ãããžã§ã¯ãã«ã¯äœããããŸããïŒ ã¹ã¿ã€ã«ã·ãŒãããããéçããŒã¿ïŒèæ¯ç»åïŒãè¿ãããhtmlãã³ãã¬ãŒãããããå°ãªããšã2ã€ã®ãã¡ã€ã«ããããŸã-ã¢ããªã±ãŒã·ã§ã³ããŒããŒã®2ã€ã®éšåïŒãµãŒããŒéšåãšããŒããŒã¢ããªã±ãŒã·ã§ã³èªäœïŒã ãã®ãã¹ãŠã«åºã¥ããŠãç§ã¯ãã®ãããªã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã«æ§é ãæããŸããïŒããªãã¯ä»ã®ãã®ãããããšãã§ããŸãïŒïŒ
public/ bg.png app
cssãã¡ã€ã«ã¯ããããªãã¯ãã©ã«ããŒå
ã§ã¯ãªããã¢ããªãã©ã«ããŒå
ã«ããããšã«æ³šæããŠãã ããã ããã¯ãããŒããŒãç¹å¥ãªæ¹æ³ã§ã¹ã¿ã€ã«ãæäœããããã§ãã ãã®çµæãGoogleã®èª¿æ»ïŒderbyã®äœæè
ã«ããïŒã§ç€ºãããŠããããã«ãã¹ã¿ã€ã«ã¿ã°ã®ããŒãžã®å
é ã«çŽæ¥æ¿å
¥ãããŸããããã¯ãã¹ã¿ã€ã«ãé«éã«é
眮ããããã®æè¯ã®æ¹æ³ã§ãã
ãããã£ãŠãååã®ã¬ãã¹ã³ã§è¿°ã¹ãããã«ãã¢ããªãã©ã«ããŒå
ã®ãã¹ãŠã¯
å圢ã®ããŒããŒã¢ããªã±ãŒã·ã§ã³ã§ãã ãå圢ããšããèšèã¯å¥œãã§ã¯ãªãã®ã§çç¥ããŸãããããŒããŒã®ãµãŒããŒéšåãã§ã¯ãªããããŒããŒã¢ããªã±ãŒã·ã§ã³ãšã ãèšããŸãã ããã§ã®ãã€ã³ãã¯ãããããã¹ãŠã®ãã¡ã€ã«ïŒã¢ããªå
ã®ãã¹ãŠïŒã1ã€ã«ãŸãšããŠãã¯ã©ã€ã¢ã³ããã©ãŠã¶ãŒã«1ã€ã®ãã³ãã«ïŒããŒã¹ïŒãæäŸããããããããããŸãšãããã®ã§ãã
äžè¬çã«ïŒå°æ¥ïŒããããžã§ã¯ããè€æ°ã®ããŒããŒã¢ããªã±ãŒã·ã§ã³ïŒã¯ã©ã€ã¢ã³ãããŒãã管çããã«ãªã©ïŒã«åå²ã§ããŸãã ããã¯ãäžèŠãªããŒã¿ïŒãã³ãã¬ãŒããã¹ã¿ã€ã«ãã³ãŒãïŒãæäŸããªãããšãšãæ¥ç¶æ§ãæžããããšã®2ã€ã®çç±ã§æ£åœåãããŸãã ã€ãŸããæ¬¡ã®ããã«ãªããŸãããããžã§ã¯ãã«ã¯ã1ã€ã®ãµãŒããŒããŒããšè€æ°ã®ããŒããŒã¢ããªã±ãŒã·ã§ã³ïŒãã®å Žåã¯2ã€ïŒããããŸãã
package.jsonãã¡ã€ã«ã§ã¯ãäŸåé¢ä¿ã¯åã2ã€ã®ã¢ãžã¥ãŒã«ïŒderby@0.6.0-alpha5ãšderby-starterã«ãªããŸãã
ã¯ããã«
ãã¡ã€ã«æ§é ãäœæããŸãã æåã«ç€ºãããªã³ã¯ããèæ¯ç»åãšã¹ã¿ã€ã«ãããŠã³ããŒããã
npm init
ã䜿çšããŠpackage.jsonãäœæã
npm init
ïŒåã®ã¬ãã¹ã³ã§ç¢ºèªã§ããŸãïŒã
åã®äŸã®ããã«ãHtmlã¯å°ã調æŽãããŠããŸãããŸããå®çŸ©æžã¿ã®
Body:
ãã³ãã¬ãŒãã«ããå¿
èŠããããŸã
Body:
次ã«ãããããŒãã¡ã€ã³ãããã¿ãŒãå¥ã
ã®ããŒããŒãã³ãã¬ãŒãã«é
眮ããŸãã
æçµçãªindex.html <Body:> <section id="todoapp"> <view name="header"/> <view name="main"/> <view name="footer"/> </section> <header:> <header id="header"> <h1>todos</h1> <form id="todo-form"> <input id="new-todo" placeholder="What needs to be done?" autofocus> </form> </header> <main:> <section id="main"> <input id="toggle-all" type="checkbox"> <label for="toggle-all">Mark all as complete</label> <ul id="todo-list"> <li> <div class="view"> <input class="toggle" type="checkbox"> <label>hello</label> <button class="destroy"> </button> </div> <form > <input class="edit"> </form> </li> </ul> </section> <footer:> <footer id="footer"> <span id="todo-count"><strong>0</strong> <span>items left</span> </span> <ul id="filters"> <li><a href="/" class="selected">All</a></li> <li><a href="/active">Active</a></li> <li><a href="/completed">Completed</a></li> </ul> <button id="clear-completed">Clear completed (0)</button> </footer>
ãæ°ã¥ããããããŸããããç¬èªã®ãã³ãã¬ãŒãã®åŒã³åºãã¯ã
view
ã¿ã°ã䜿çšããŠè¡ãã
view
ãviewã¿ã°ã§ã¯ããã³ãã¬ãŒãã®ååã«ãã£ãŠãã³ãã¬ãŒãã®ååãèšå®ãããŸãã
ãŸãããã©ãŠã¶ã§çµæã確èªããŠæ©èœã匷åã§ããããã«ãæå°éã®äœæ¥ã³ãŒããäœæããŸãã
åã®äŸã®server.jsãã¡ã€ã«ã¯ããããžã§ã¯ãã®æ§é ãèæ
®ããŠéçãã¡ã€ã«ãã¬ã³ããªã³ã°ããããã«ãããã«æ¡åŒµãããŠããŸãã
server.js var server = require('derby-starter'); var appPath = __dirname + '/app'; var options = { static: __dirname + '/public' }; server.run(appPath, options);
ãããžã§ã¯ãã®æè²çæ§è³ªã«ãããderby-starterã¢ãžã¥ãŒã«ããµãŒããŒéšåãšããŠäœ¿çšããŠããããšãæãåºãããŠãã ããã å
åŽãèŠããšãéçãã¡ã€ã«ã®æ»ãã¯ãexpress-static static-middlwareã®å€å
žçãªäœ¿çšæ³ã§ãã
èªåã§èŠãŠ
ãã ãã ã
æå°index.jsïŒ var derby = require('derby'); var app = module.exports = derby.createApp('todos', __filename);
ãã¹ãŠãnpm startïŒãŸãã¯çŽæ¥ããŒãserver.jsïŒãèµ·åãããã©ãŠã¶ã«
httpïŒ// localhostïŒ3000 /çµæã衚瀺ãããŸãïŒ

ã¬ã€ã¢ãŠãã®ã¹ã¿ã€ã«ã远ãã€ããã éå§ãããŸããã
ãã¶ã€ã³URL
ååã®ã¬ãã¹ã³ã§ã¯ãããŒããŒéçºè
ã¯ãããžã§ã¯ããURLã«åå²ããŠéçºãéå§ããå¿
èŠããããšè¿°ã¹ãŸããã ããã¯ãæ€çŽ¢ãšã³ãžã³ã奜ãã¯ã©ã€ã¢ã³ããšãµãŒããŒã®äž¡æ¹ã§ããŒãžãçæããããŒããŒã®èœåã«ãããã®ã§ãã ãã®ãããAngularããŒãžã§ã³ã®åŠç¿äžã«ãããã¿ãŒã«URLã倿Žãã3ã€ã®ãªã³ã¯ããããããã«å¿ããŠã¿ã¹ã¯ããšã®ãã£ã«ã¿ãŒãããããšã«æ°ä»ããŸããã ããã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã«3ã€ã®getèŠæ±ãã³ãã©ãŒãå¿
èŠã§ããããšãçè§£ããŠããŸãã æ¬¡ã®ãããªãã®ïŒ
app.get('/', getAllTodos); app.get('/active', getActiveTodos); app.get('/completed', getCompletedTodos);
ãããã®ããŒãžããã¹ãŠç°ãªãå Žåãããã¯æ£åœåãããŸãããç§ãã¡ã«ãšã£ãŠããããã®éã®å¯äžã®éãã¯ãã£ã«ã¿ãŒã§ãããããã³ãŒããæå°éã«è€è£œããããšããŸãã
èšèšããŒã¿
ã¿ã¹ã¯èªäœã¯ã
todos
ã³ã¬ã¯ã·ã§ã³ã«ä¿åãããŸãã åã¿ã¹ã¯ã¯2ã€ã®ãã£ãŒã«ãã§è¡šãããŸãã
- ããã¹ã-ã¿ã¹ã¯ã®èª¬æ
- completed-ã¿ã¹ã¯ãå®äºããããšã®å
å
ããã«ããã¡ããåã¿ã¹ã¯ã«ãidãã£ãŒã«ããããããšã远å ããå¿
èŠããããŸã-ããŒããŒã¯ã³ã¬ã¯ã·ã§ã³ã«ã¢ã€ãã ã远å ãããšãã«èªåçã«è¿œå ããŸãã
ãããã£ãŠãããŒããŒã®æ¹æ³è«ã«åŸã£ãŠãã³ã³ãããŒã©ãŒïŒurlãžã®èŠæ±ãåŠçãã颿°ïŒã§ãrenderãåŒã³åºãåã«ãããŒã¿ãæºåããããŒã¿ãæŽæ°ããããã®ãµãã¹ã¯ãªãã·ã§ã³ãç»é²ããå¿
èŠããããŸãã ãã³ãã©ãŒã¯ãæŠç¥çã«æ¬¡ã®ããã«ãªããŸãã
function getTodos(page, model){ model.subscribe('todos', function(){ page.render(); }); }
ããã¯ã»ãŒåãã§ãããå
ã«é²ãåã«ïŒ3ã€ã®ã¯ãšãªãã¹ãŠã«å¯ŸããŠ1ã€ã®ã³ã³ãããŒã©ãŒãäœæããã¿ã¹ã¯ã«å¯ŸããŠç°ãªããã£ã«ã¿ãŒã®ã¿ã䜿çšããããã«ïŒãããŒããŒã¢ãã«ã«ã€ããŠããã€ãã®ããšãåŠã¶å¿
èŠããããŸãã
- ã¢ã³ããŒã¹ã³ã¢ã§å§ãŸãããã¹ãïŒã_sessionããã_ pageããªã©ïŒ
- ã_pageãã®æ©èœã¯äœã§ãã
- ããŒããŒãã£ã«ã¿ãŒãšã¯
- ã³ã¬ã¯ã·ã§ã³å
ã®ç¹å®ã®ããŒã¿ãžã®åç
§ã¯äœã§ãã
ååã®ã¬ãã¹ã³ã§ã¯ãããããããã¹ãã«ã€ããŠè©±ããŸããã ã¢ãã«ã®æäœã§ãããã䜿çšããŸãã ããšãã°ãããŒã¿ããµãã¹ã¯ã©ã€ãããå ŽåïŒmodel.subscribeïŒ 'path'ïŒãã¢ãã«ã®ããŒã¿ãåä¿¡ããã³æžã蟌ãå ŽåïŒ
model.get('')
ã
model.set('', )
ã ãã¹ã®äŸïŒ
- 'todos'-todosã³ã¬ã¯ã·ã§ã³å
šäœãžã®ãªã³ã¯
- 'users.42'-id = 42ã®ãŠãŒã¶ãŒã³ã¬ã¯ã·ã§ã³ã®ãšã³ããªãåç
§ããŸã
ã ããããã«ã ãåãã®ãšããããã¹ã®æåã®ã»ã°ã¡ã³ãã¯ã³ã¬ã¯ã·ã§ã³ã®ååã§ãã ãã®ããŒããŒåã¯ãã©ãã³æåããŸãã¯æå$ãŸãã¯_ã§å§ããããšãã§ããŸãã $ããã³_ã§å§ãŸããã¹ãŠã®ã³ã¬ã¯ã·ã§ã³ã¯ç¹å¥ã§ããããµãŒããŒãšåæããŠããŸããïŒãããã¯ã¢ãã«ã«å¯ŸããŠããŒã«ã«ã§ããã1ã€ã®ã¢ãã«ã®ã¿ãããŒããŒã¢ããªã±ãŒã·ã§ã³ã§äœæãããŸãïŒã $ã§å§ãŸãã³ã¬ã¯ã·ã§ã³ã¯ãç¬èªã®ããŒãºã®ããã«ããŒããŒãäºçŽããŸããã éçºè
ã¯ãã¢ã³ããŒã¹ã³ã¢ã§å§ãŸãã³ã¬ã¯ã·ã§ã³ã䜿çšããŸãã
å°ãå®éšããŠã¿ãŸãããã ãã©ãŠã¶ãŒã§éçºè
ã³ã³ãœãŒã«ãéããã
app.model.get()
ãšå
¥åããŠãåºåã衚瀺ããŸãã
ã_ãã³ã¬ã¯ã·ã§ã³ã«ã¯ç¹å¥ãªãã®ã1ã€ãã
_page
ã¯ãURLã
_page
ãããã³ã«
_page
ã
_page
ããã«ãããããããçš®é¡ã®äœæ¥ããŒã¿ãä¿åããã®ã«éåžžã«äŸ¿å©ã§ãã ãã®ã¬ãã¹ã³ã§ã¯ãããå€ãã®äŸãèŠãããšãã§ããŸãã
ãã£ã«ã¿ãŒã«ç§»ããŸãããã ã¢ãã«ã®ããã¥ã¡ã³ããèªããšãããŒããŒã«ã¯ãªã¢ã¯ãã£ãããŒã¿ã®åŠçã容æã«ããããŸããŸãªã¡ã«ããºã ãããããšãããããŸãã ããã¯ãããšãã°ããªã¢ã¯ãã£ã颿°ãããŒã¿ã§çºçããããŸããŸãªã€ãã³ãã®ãµãã¹ã¯ãªãã·ã§ã³ãããŒã¿ãã£ã«ã¿ãŒãããŒã¿ãœãŒã¿ãŒãªã©ã§ãã
ãã£ã«ã¿ãŒã«ã€ããŠèª¬æããŸãããã ããšãã°ãã¢ã¯ãã£ããªã¿ã¹ã¯ã®ã¿ã衚瀺ãããã£ã«ã¿ãŒãå®è£
ããã«ã¯ã©ãããã°ããã§ããïŒ
ç¹å®ã®ååã§ãã£ã«ã¿ãŒé¢æ°ãç»é²ããŸãïŒååã¯ãã³ãã«ã§ã®ã·ãªã¢ã«åã«å¿
èŠã§ãïŒã ããã¥ã¡ã³ãã«ã¯ãããããå³å¯ã«
app.on('model')
ã«ç»é²ããå¿
èŠããããšæžãããŠããŸã
app.on('model', function(model) { model.fn('completed', function(item) { return item.completed; }); });
ããã«ã³ã³ãããŒã©ãŒã§ããã®ãã£ã«ã¿ãŒã䜿çšããŠtodosã³ã¬ã¯ã·ã§ã³ããã£ã«ã¿ãŒåŠçããŸãã
function getPage(page, model){ model.subscribe('todos', function() { var filter = model.filter('todos', 'completed') filter.ref('_page.todos'); page.render(); }); }
ããã§ãè¡
filter.ref('_page.todos');
ã¯éåžžã«éèŠã§ã
filter.ref('_page.todos');
ããã®äžã§ããã£ã«ã¿ãªã³ã°ããããtodosãã
_page.todos
ãã¹ã§å©çšå¯èœã«ãªããŸãã ãã¹ãŠããŸãšãããšãã³ã³ãããŒã©ãŒã䜿çšãããã£ã«ã¿ãŒã³ãŒããããã«ææ¡ããŸãã
app.on('model', function(model) { model.fn('all', function(item) { return true; }); model.fn('completed', function(item) { return item.completed;}); model.fn('active', function(item) { return !item.completed;}); }); app.get('/', getPage('all')); app.get('/active', getPage('active')); app.get('/completed', getPage('completed')); function getPage(filter){ return function(page, model){ model.subscribe('todos', function() { model.filter('todos', filter).ref('_page.todos'); page.render(); }); } }
ãæ°ã¥ããããããŸãããããã¹ãŠãçµ±äžããããã«ãåœã®ãã£ã«ã¿ãŒãããã¹ãŠãäœæããå¿
èŠããããŸããããããã¯ãã€ã¯ã®æ¬ åŠã«ãšã£ãŠå€§ããªæéã§ã¯ãªããšæããŸãã
ããŠãå°ãæ°ãæ£ããŸããã ã¢ããªã±ãŒã·ã§ã³ã埩掻ãããŸãããã
ã¿ã¹ã¯ã®è¿œå ãšãªã¹ã
ã¬ã€ã¢ãŠãã®ããŒã¿å
¥åã®å
¥åã¯æ¬¡ã®ããã«ãªããŸãã
<form id="todo-form"> <input id="new-todo" placeholder="What needs to be done?" autofocus> </form>
ããŒããŒã®å€å
žçãªãã¿ãŒã³ïŒå€ãã®ææ°ã®ãã¬ãŒã ã¯ãŒã¯ãšåæ§ïŒã¯ããªã¢ã¯ãã£ããã€ã³ãã£ã³ã°ã§ãã å
¥åã§å
¥åããå€ã
_page
ãã¹ã«
_page
ãŸãã
enter
ã¯ãªãã¯ãåŠçããããã«ããã©ãŒã ã®
submit
ã€ãã³ããã³ãã©ãŒãç»é²ã
enter
ã
<form id="todo-form" on-submit="addTodo(_page.newTodo)"> <input id="new-todo" placeholder="What needs to be done?" autofocus value="{{_page.newTodo}}"> </form>
on-submit
ã¯ãªããèªç¶ã«
on-click
ã
on-keyup
ã
on-focus
èšè¿°
on-click
ããšãã§ã
on-click
-ã€ãŸããããã¯ããŒããŒã§ã€ãã³ããåŠçããæšæºçãªæ¹æ³ã§ãã
app.proto
ãã³ãã©ãŒãé
眮ã
app.proto
ïŒããŒããŒã³ã³ããŒãã³ãã«ã€ããŠèª¬æãããšãã«ãåã³ã³ããŒãã³ãããã®ãã³ãã©ãŒãããèªäœã«æ ŒçŽããããšãããããŸãããä»ã®ãšãããããè¡ããŸãïŒã
app.proto.addTodo = function(newTodo){ if (!newTodo) return; this.model.add('todos', { text: newTodo, completed: false }); this.model.set('_page.newTodo', ''); };
ããã¹ãã空ãã©ããã確èªããã¿ã¹ã¯ãã³ã¬ã¯ã·ã§ã³ã«è¿œå ããŠã
input
ã¯ãªã¢ã
input
ã ãã³ãã©ãŒã«ãã©ã¡ãŒã¿ãŒã1ã€ãããªãããšã«æ°ã¥ãããããããŸãããäœããã®çç±ã§ã€ãã³ããªããžã§ã¯ããŸãã¯htmlèŠçŽ èªäœãžã®åç
§ãå¿
èŠãªå Žåã¯ã次ã®ããã«htmlã«æç€ºçã«èšè¿°ããå¿
èŠããããŸãã
on-submit="addTodo(_page.newTodo, $event, $element)"
ã
$event
ããã³
$element
ã¯ããŒããŒèªäœã«ãã£ãŠåããããç¹å¥ãªãã©ã¡ãŒã¿ãŒã§ãã
ãã£ã«ã¿ãªã³ã°ãããã¿ã¹ã¯ãªã¹ãã®åºå
ul
èŠçŽ ãç·šéããŸãã
<ul id="todo-list"> {{each _page.todos as #todo, #index}} <li class="{{if #todo.completed}}completed{{/}}"> <div class="view"> <input class="toggle" type="checkbox" checked="{{#todo.completed}}"> <label>{{#todo.text}}</label> <button class="destroy"> </button> </div> <form> <input class="edit"> </form> </li> {{/each}} </ul>
ã ããäœãããïŒ
- ãã¹ãŠã®ToDoãã«ãŒãããŸãïŒãã£ã«ã¿ãŒæžã¿ïŒ-ãããã®èŠçŽ ãäœæããŸã-li
lable
ã¿ã¹ã¯ã®èª¬æãå°å·ããcheckbox
ãtodo.completed
- ã¿ã¹ã¯ãå®äºããå Žåã
li
ã¿ã°ã®completed
ã¯ã©ã¹ãèšå®ããŸãã
ã¢ã€ãã ãåé€ãã
ããã¯åºæ¬çã«è¡ãããŸãïŒ
<button class="destroy" on-click="delTodo(#todo.id)"> </button>
app.proto.delTodo = function(todoId){ this.model.del('todos.' + todoId); };
ãããŠãããã«çãããããšãã§ããŸããã
<button class="destroy" on-click="model.del('todos.' + #todo.id)"> </button>
ãã¹ãŠã®ãå®äºãã¿ã¹ã¯ã®åé€ãåæ§ã§ãïŒãå®äºå®äºããã¿ã³ã¯å³äžã«ãããŸãïŒã
<button id="clear-completed" on-click="clearCompleted()"> Clear completed (0) </button>
app.proto.clearCompleted = function(){ var todos = this.model.get('todos'); for (var id in todos) { if (todos[id].completed) this.model.del('todos.'+id); } }
èŠçŽ ãç·šéãã
ããã«ã¯ãªãã¯ãããšãã¿ã¹ã¯ã¯ç·šéã¢ãŒãã«ãªããŸãã ã¬ã€ã¢ãŠããã倿ãããšããã®ã¢ãŒãã«åãæ¿ãããšãã¯ã察å¿ãã
li
èŠçŽ ã«
editing
ã¯ã©ã¹ã远å ããå¿
èŠããããŸãã ãŸããéäžã§ãããã«ã¯ãªãã¯ããŠçºçããéžæãåãé€ããå¿
èŠãªå
¥åã«æ£ãããã©ãŒã«ã¹ãåãããå¿
èŠããããŸãã
次ã®ããã«ãããè¡ãããšãææ¡ããŸãïŒãã¹
-_page.editã䜿çšããŠãç·šéããã¿ã¹ã¯ã«é¢ããæ
å ±ãä¿åããŸãã ããã§ãç·šéããã¿ã¹ã¯ã®IDãšããã¹ããä¿åããŸãã
ããã¹ããåå¥ã«ä¿åããã®ã¯ãªãã§ããããã§ã«ã¿ã¹ã¯èªäœã«ä¿åãããŠããŸããïŒããã¯ãã¹ãŠç®æšã«äŸåããŸãã ããã¹ããã¿ã¹ã¯ããçŽæ¥å
¥åã«æ¥ç¶ããå ŽåããŠãŒã¶ãŒã¯ããŒã¿ããŒã¹å
ã®èŠçŽ ãçŽæ¥ç·šéããŸãã ã€ãŸãããã®ç·šéïŒãã¿ã³ãæŒããã³ã«ïŒã¯ããã©ãŠã¶ãŒã§ä»ã®ãŠãŒã¶ãŒã«å³åº§ã«è¡šç€ºãããŸãã ããã«ãè€æ°ã®ãŠãŒã¶ãŒãåæã«ããã¹ããç·šéãããã¹ãŠã®å€æŽã衚瀺ã§ããŸãããããã¯å¿
èŠãªãã®ã§ã¯ãããŸããã éåžžã®ã·ããªãªã¯ãæçµçã«ç·šéãããããŒã¿ã®ããŒã¿ããŒã¹ã«ã³ãããããããã³ããããæåŠããããšã§ããã€ãŸãããŠãŒã¶ãŒãenter
ããŒãæŒããå Žåã«ã®ã¿ããã¹ãŠã®ãŠãŒã¶ãŒã«å¯ŸããŠãã¹ãŠãæŽæ°ããå¿
èŠãããenter
ã
ãã®ãããæ¬¡ã®ãã¹ãŠãå®è£
ããŸãã
<ul id="todo-list"> {{each _page.todos as #todo}} <li class="{{if #todo.completed}}completed{{/}} {{if _page.edit.id === #todo.id}}editing{{/}}"> <div class="view"> <input class="toggle" type="checkbox" checked="{{#todo.completed}}"> <label on-dblclick="editTodo(#todo)">{{#todo.text}}</label> <button class="destroy" on-click="delTodo(#todo.id)"> </button> </div> <form on-submit="doneEditing(_page.edit)"> <input id="{{#todo.id}}" class="edit" value="{{_page.edit.text}}" on-keyup="cancelEditing($event)"> </form> </li> {{/each}} </ul>
app.proto.editTodo = function(todo){ this.model.set('_page.edit', { id: todo.id, text: todo.text }); window.getSelection().removeAllRanges(); document.getElementById(todo.id).focus() } app.proto.doneEditing = function(todo){ this.model.set('todos.'+todo.id+'.text', todo.text); this.model.set('_page.edit', { id: undefined, text: '' }); } app.proto.cancelEditing = function(e){
ããã«ã¯ãªãã¯ãããšã
editTodo颿°ã
ããªã¬ãŒãã ããã®äžã«
_path.editãå
¥åããäžèŠãªéžæãåé€ããå¿
èŠãªå
¥åã«ãã©ãŒã«ã¹ãåãæ¿ããŸãïŒããã§ã¯ãå
¥å
id = todo.id
ãæå®ããŠå°ãæµ®æ°ããŸããïŒã
ç·šéãçµäºããããenterãŸãã¯esqãæŒããŸãã ãããã£ãŠã
doneEditing
ã
cancelEditing
ã®2ã€ã®ãã³ãã©ãŒã®ãããããèµ·åããŸãã ã³ãŒããåŠã¶-æ°ããããšã¯äœããªãã
ã¢ã¯ãã£ãããã³å®äºããã¿ã¹ã¯ã®æ°-ãªã¢ã¯ãã£ãæ©èœ
ãããã£ãŠãæåŸã«è¡ãããšã¯ãã¢ã¯ãã£ããªã¿ã¹ã¯ãšå®äºããã¿ã¹ã¯ã®æ°ãããã¿ãŒã«åºåããããšã§ãã ããã¯ããªã¢ã¯ãã£ã颿°ãšã¯äœãã説æããæ£åœãªçç±ã§ãã
ãããžã§ã¯ãã®ã¢ãŒããã¯ãã£ã«é¢ããå°ããªçºèšç§ãéžæããã¢ããªã±ãŒã·ã§ã³å®è£
ãªãã·ã§ã³ãå¯äžã®ãã®ã§ã¯ãªãããšã«æ³šæããŠãã ããã ãããèãããšãç¹å®ã®ãããžã§ã¯ããããã«live-queryã䜿çšããŠé ã«æµ®ãã³ãŸã-ããã¯ãããŒã¿ããŒã¹ã«å¯ŸããŠmongo-requestãè¡ãããšãã§ãããã1ã€ã®çŽ æŽãããããŒããŒã¡ã«ããºã ã§ããããã®çµæã¯äºåŸçã«æŽæ°ãããŸãã ãã¡ãããã¯ãšãªã§ã¯ãããŸããŸãªéžæããœãŒããæ°éå¶éïŒ $limit
ã $skip
ã $orderby
ïŒã䜿çšã§ããŸãã ã³ã¬ã¯ã·ã§ã³å
ã®èŠçŽ ã®æ°ãïŒä»»æã®éžæãå«ããŠïŒè¿ãã¯ãšãªãäœæããããšãã§ããŸã-ããã¯ãŸãã«ç§ãã¡ã®å Žåã§ãã æ¬¡ã®æçš¿ã®ããããã§ãã©ã€ããã¯ãšãªã調æ»ããŸãããå®éã®ã¢ããªã±ãŒã·ã§ã³ã§ããã䜿çšããããªã¢ã¯ãã£ã颿°ã«ããå®è£
ã瀺ãããšãé©åã§ãããšèããŸããã
ãããã£ãŠããªã¢ã¯ãã£ã颿°ã¯ãããŒã¿ã倿Žããããã³ã«ããªã¬ãŒããã颿°ã§ãã ã€ãŸãããã®ç¹å®ã®ãªã¢ã¯ãã£ã颿°ããããã®ç¹å®ã®ããŒã¿ã®å€åãç£èŠããããšã瀺ãå¿
èŠããããŸãã ãã®ããŒã¿ã¯ããã©ã¡ãŒã¿ãŒãšããŠãã®é¢æ°ã«å
¥åãããŸãã æ¬¡ã«ã圌女ã¯äœããèšç®ããçµæãè¿ããŸãã ãã®çµæã¯ãç¹å®ã®ããã¹ãã«é¢é£ä»ããããŠããŸã...
ããŠãããã¯ãã¹ãŠæœè±¡çã§ããããããã£ãŠèªã¿ã«ããã§ãã äŸã䜿çšããŸãããã ã¢ã¯ãã£ããªã¿ã¹ã¯ãšå®äºããã¿ã¹ã¯ãå«ãTodoã®ã³ã¬ã¯ã·ã§ã³ããããŸãã ã³ã¬ã¯ã·ã§ã³ã®å€æŽæã«ãã©ããïŒããšãã°ã
_page.counters
ãã¹ã«æ²¿ã£ãŠïŒã§ã¢ã¯ãã£ããªã¿ã¹ã¯ãšå®äºããã¿ã¹ã¯ã®ã«ãŠã³ã¿ãŒã«ã¢ã¯ã»ã¹ã§ãããš
_page.counters
ã§ãã æ¬¡ã®ãããªãã®ïŒ
_page.counters = { active: 2, completed: 3 }
次ã«ããã®ããŒã¿ãããã¿ãŒã«ç°¡åã«è¡šç€ºã§ããŸãã
ãããã®ã«ãŠã³ã¿ãŒãååŸãã1ã€ã®ãªãã·ã§ã³ã¯ããªã¢ã¯ãã£ã颿°ã䜿çšããããšã§ãã ãããã¯ãã£ã«ã¿ãŒãšåãæ¹æ³ã§ç»é²ãããŸãïŒ
app.on('model', function(model) { model.fn('all', function(item) { return true; }); model.fn('completed', function(item) { return item.completed;}); model.fn('active', function(item) { return !item.completed;}); model.fn('counters', function(todos){ var counters = { active: 0, completed: 0 }; for (var id in todos) { if(todos[id].completed) counters.completed++; else counters.active++; } return counters; }) });
ããã
counters
æ©èœã®ç»é²æ¹æ³ã§ãããããã ãã§ã¯ãããŸããã é©åãªã¿ã€ãã³ã°ã§èµ·åãããã¹ã«çµã³ä»ããå¿
èŠããããŸãã ããã¯ã
model.start
颿°ã䜿çšããŠã³ã³ãããŒã©ãŒã§å®è¡ãããŸãã
model.subscribe('todos', function () { model.filter('todos', filter).ref('_page.todos'); model.start('_page.counters', 'todos', 'counters'); page.render(); });
ããã§ããã³ãã¬ãŒãã§ã«ãŠã³ã¿ãŒã䜿çšã§ããããã«ãªããŸããã ããã¿ãŒã宿ãããŠããŸãïŒ
<footer:> <footer id="footer"> <span id="todo-count"><strong>{{_page.counters.active}} </strong> <span>items left</span> </span> <ul id="filters"> <li><a href="/" class="{{if $render.url==='/' }}selected{{/}}">All</a></li> <li><a href="/active" class="{{if $render.url==='/active' }}selected{{/}}">Active</a></li> <li><a href="/completed" class="{{if $render.url==='/completed'}}selected{{/}}">Completed</a></li> </ul> <button id="clear-completed" on-click="clearCompleted()" class="{{if _page.counters.completed==0}}hidden{{/}}"> Clear completed ({{_page.counters.completed}}) </button> </footer>
å®äºããã¿ã¹ã¯ããªãå Žåã¯ãå¿
èŠãªã«ãŠã³ã¿ãŒã衚瀺ãããšåæã«ããã¯ãªã¢å®äºããã¿ã³ãé衚瀺ã«ããŸããã ãŸãããã©ãŠã¶ãŒã³ã³ãœãŒã«ã§
app.model.get()
調æ»äžã«ååŸããæ
å ±ã䜿çšããŠã
selected
ã¯ã©ã¹ãã¢ã¯ãã£ããªãªã³ã¯ã«è¿œå ããŸããã ã¯ããäºçŽæžã¿ã®
$render
ã³ã¬ã¯ã·ã§ã³ã«ã¯ãããŸããŸãªæçšãªæ
å ±ãç¹ã«ã¬ã³ããªã³ã°ã«
url
ãã
url
ãŠããŸãã ããäžåºŠã³ã³ãœãŒã«ãèŠãŠãã ããã
ãŸãšã
äœãèµ·ãã£ãã®ãã詊ããããã€ãã®ã¿ããéããŠããã¹ãŠãåæãããŠããããšã確èªããŸãã

ã³ãŒããæ¯èŒãããå Žåã®
githubãããžã§ã¯ãã
PS次ã®derbyjsã®èšäºãèŠéããããªãå Žåã¯ããããã¡ã€ã«ã®æŽæ°ã賌èªããŠãã ããïŒ
zag2art ã ç§ã¯èªåã§ãã£ãŠããŸã-ããã§ã¯ãç¹å®ã®ïŒéåžžã«è峿·±ãïŒããããã©ãã«ãŒã«è¿œå ããæ¹æ³ããªããããèŠéãããšã¯ãããŸããã
derbyjs â
github