Last active
January 3, 2016 09:09
-
-
Save knjname/8440723 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| global = @ | |
| $ -> | |
| # モデル | |
| model = | |
| golds: 0 | |
| products: [] | |
| events: {} | |
| greeting: '' | |
| cart: {} | |
| itemBag: {} | |
| cartTotal: 0 | |
| get: (property) -> @[property] | |
| set: (property, value) -> | |
| console.log "Property #{property} has been changed: #{@[property]} => #{value}" | |
| @[property] = value | |
| @fire property | |
| calculateCartTotal: -> | |
| total = 0 | |
| for itemName, count of @cart | |
| total += count * (p.price for p in @products when p.name is itemName)[0] | |
| total | |
| put: (property, key, value) -> | |
| (@[property] ?= {})[key] = value | |
| if property is 'cart' | |
| @set 'greeting', if value is 0 then 'おうおう買わないのかい?' else 'たくさん買ってくれよ!' | |
| @fire property | |
| buy: -> | |
| cartTotal = @calculateCartTotal() | |
| if cartTotal is 0 | |
| @set 'greeting', '何か商品選んでくれよ' | |
| else if cartTotal > @golds | |
| @set 'greeting', '悪いけど、金が足りないみたいだな。' | |
| else | |
| @set 'greeting', 'まいどあり!' | |
| @set 'golds', @golds - cartTotal | |
| for itemName, count of @cart | |
| @put 'itemBag', itemName, (@itemBag[itemName] or 0) + count | |
| @set 'cart', {} | |
| add: (property, item) -> | |
| (@[property] ?= []).push item | |
| @fire property | |
| fire: (property) -> | |
| for fn in (@events[property] ?= []) | |
| fn() | |
| on: (property, fn) -> | |
| (@events[property] ?= []).push fn | |
| # ビュー | |
| $frame = $('#itemshop') | |
| $greeting = $frame.find('.greeting') | |
| $golds = $frame.find('.golds') | |
| $products = $frame.find('.products') | |
| $cart_total = $frame.find('.cart_total') | |
| $buy = $frame.find('.buy') | |
| $item_bag = $frame.find('.item_bag') | |
| # (無限ループ対策 モデル変更 → ビュー変更 → モデル変更 ... の無限ループ回避) | |
| # 本来なら、ループ検出したら打ち切る実装にしたほうがいいね | |
| whileEventProcess = false | |
| whileEvent = (fn) -> | |
| try | |
| whileEventProcess = true | |
| fn() | |
| finally | |
| whileEventProcess = false | |
| # コントローラ | |
| controller = | |
| init: -> | |
| model.on 'golds', -> | |
| $golds.text(model.get 'golds') | |
| model.on 'products', -> | |
| $trs = for p in model.get('products') | |
| $('<tr>').append [ | |
| $('<td>').text p.name | |
| $('<td>').text "#{p.price} ゴールド" | |
| $('<td>').append ( | |
| do => | |
| $select = $('<select>').data(product: p).addClass('itemCount').append [ | |
| $('<option>').attr({value: cnt}).text(cnt) for cnt in [ 0..9 ] | |
| ]... | |
| $select.val (model.get('cart')[p.name] or 0) | |
| $select | |
| ) | |
| ]... | |
| $products.html('').append $trs... | |
| model.on 'cart', -> | |
| $cart_total.text(model.calculateCartTotal()) | |
| for select in $products.find('select') | |
| $(select).val 0 | |
| for itemName, count of model.get 'cart' when itemName is $(select).data('product').name | |
| $(select).val count | |
| model.on 'greeting', -> | |
| $greeting.text(model.get 'greeting') | |
| model.on 'itemBag', -> | |
| $item_bag.text(JSON.stringify model.get('itemBag')) | |
| $frame.on | |
| change: -> | |
| controller.onItemCountChange $(@).data('product').name, + $(@).val() | |
| , 'select.itemCount' | |
| $buy.click -> | |
| controller.onBuy() | |
| model.set 'golds', 1000 | |
| model.set 'greeting', 'へいいらっしゃい!' | |
| model.add 'products', { name: 'ポーション', price: 50 } | |
| model.add 'products', { name: 'ハイポーション', price: 250 } | |
| model.add 'products', { name: 'エーテル', price: 500 } | |
| model.add 'products', { name: 'フェニックスの尾', price: 1000 } | |
| onItemCountChange: (itemName, count) -> whileEvent => | |
| model.put 'cart', itemName, count | |
| onBuy: -> whileEvent => | |
| model.buy() | |
| setTimeout (-> model.add 'products', {name: '10秒滞在記念アイテム', price: 200}), 10 * 1000 | |
| setTimeout (-> model.add 'products', {name: '50秒滞在記念アイテム', price: 1400}), 50 * 1000 | |
| $frame.find('.make_money').click -> | |
| model.set 'golds', (model.get 'golds') + 1000 | |
| controller.init() | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Generated by CoffeeScript 1.6.3 | |
| (function() { | |
| var global; | |
| global = this; | |
| $(function() { | |
| var $buy, $cart_total, $frame, $golds, $greeting, $item_bag, $products, controller, model, whileEvent, whileEventProcess; | |
| model = { | |
| golds: 0, | |
| products: [], | |
| events: {}, | |
| greeting: '', | |
| cart: {}, | |
| itemBag: {}, | |
| cartTotal: 0, | |
| get: function(property) { | |
| return this[property]; | |
| }, | |
| set: function(property, value) { | |
| console.log("Property " + property + " has been changed: " + this[property] + " => " + value); | |
| this[property] = value; | |
| return this.fire(property); | |
| }, | |
| calculateCartTotal: function() { | |
| var count, itemName, p, total, _ref; | |
| total = 0; | |
| _ref = this.cart; | |
| for (itemName in _ref) { | |
| count = _ref[itemName]; | |
| total += count * ((function() { | |
| var _i, _len, _ref1, _results; | |
| _ref1 = this.products; | |
| _results = []; | |
| for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | |
| p = _ref1[_i]; | |
| if (p.name === itemName) { | |
| _results.push(p.price); | |
| } | |
| } | |
| return _results; | |
| }).call(this))[0]; | |
| } | |
| return total; | |
| }, | |
| put: function(property, key, value) { | |
| (this[property] != null ? this[property] : this[property] = {})[key] = value; | |
| if (property === 'cart') { | |
| this.set('greeting', value === 0 ? 'おうおう買わないのかい?' : 'たくさん買ってくれよ!'); | |
| } | |
| return this.fire(property); | |
| }, | |
| buy: function() { | |
| var cartTotal, count, itemName, _ref; | |
| cartTotal = this.calculateCartTotal(); | |
| if (cartTotal === 0) { | |
| return this.set('greeting', '何か商品選んでくれよ'); | |
| } else if (cartTotal > this.golds) { | |
| return this.set('greeting', '悪いけど、金が足りないみたいだな。'); | |
| } else { | |
| this.set('greeting', 'まいどあり!'); | |
| this.set('golds', this.golds - cartTotal); | |
| _ref = this.cart; | |
| for (itemName in _ref) { | |
| count = _ref[itemName]; | |
| this.put('itemBag', itemName, (this.itemBag[itemName] || 0) + count); | |
| } | |
| return this.set('cart', {}); | |
| } | |
| }, | |
| add: function(property, item) { | |
| (this[property] != null ? this[property] : this[property] = []).push(item); | |
| return this.fire(property); | |
| }, | |
| fire: function(property) { | |
| var fn, _base, _i, _len, _ref, _results; | |
| _ref = ((_base = this.events)[property] != null ? (_base = this.events)[property] : _base[property] = []); | |
| _results = []; | |
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
| fn = _ref[_i]; | |
| _results.push(fn()); | |
| } | |
| return _results; | |
| }, | |
| on: function(property, fn) { | |
| var _base; | |
| return ((_base = this.events)[property] != null ? (_base = this.events)[property] : _base[property] = []).push(fn); | |
| } | |
| }; | |
| $frame = $('#itemshop'); | |
| $greeting = $frame.find('.greeting'); | |
| $golds = $frame.find('.golds'); | |
| $products = $frame.find('.products'); | |
| $cart_total = $frame.find('.cart_total'); | |
| $buy = $frame.find('.buy'); | |
| $item_bag = $frame.find('.item_bag'); | |
| whileEventProcess = false; | |
| whileEvent = function(fn) { | |
| try { | |
| whileEventProcess = true; | |
| return fn(); | |
| } finally { | |
| whileEventProcess = false; | |
| } | |
| }; | |
| controller = { | |
| init: function() { | |
| model.on('golds', function() { | |
| return $golds.text(model.get('golds')); | |
| }); | |
| model.on('products', function() { | |
| var $trs, p, _ref; | |
| $trs = (function() { | |
| var _i, _len, _ref, _ref1, _results, | |
| _this = this; | |
| _ref = model.get('products'); | |
| _results = []; | |
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
| p = _ref[_i]; | |
| _results.push((_ref1 = $('<tr>')).append.apply(_ref1, [ | |
| $('<td>').text(p.name), $('<td>').text("" + p.price + " ゴールド"), $('<td>').append((function() { | |
| var $select, cnt, _ref1; | |
| $select = (_ref1 = $('<select>').data({ | |
| product: p | |
| }).addClass('itemCount')).append.apply(_ref1, [ | |
| (function() { | |
| var _j, _results1; | |
| _results1 = []; | |
| for (cnt = _j = 0; _j <= 9; cnt = ++_j) { | |
| _results1.push($('<option>').attr({ | |
| value: cnt | |
| }).text(cnt)); | |
| } | |
| return _results1; | |
| })() | |
| ]); | |
| $select.val(model.get('cart')[p.name] || 0); | |
| return $select; | |
| })()) | |
| ])); | |
| } | |
| return _results; | |
| }).call(this); | |
| return (_ref = $products.html('')).append.apply(_ref, $trs); | |
| }); | |
| model.on('cart', function() { | |
| var count, itemName, select, _i, _len, _ref, _results; | |
| $cart_total.text(model.calculateCartTotal()); | |
| _ref = $products.find('select'); | |
| _results = []; | |
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
| select = _ref[_i]; | |
| $(select).val(0); | |
| _results.push((function() { | |
| var _ref1, _results1; | |
| _ref1 = model.get('cart'); | |
| _results1 = []; | |
| for (itemName in _ref1) { | |
| count = _ref1[itemName]; | |
| if (itemName === $(select).data('product').name) { | |
| _results1.push($(select).val(count)); | |
| } | |
| } | |
| return _results1; | |
| })()); | |
| } | |
| return _results; | |
| }); | |
| model.on('greeting', function() { | |
| return $greeting.text(model.get('greeting')); | |
| }); | |
| model.on('itemBag', function() { | |
| return $item_bag.text(JSON.stringify(model.get('itemBag'))); | |
| }); | |
| $frame.on({ | |
| change: function() { | |
| return controller.onItemCountChange($(this).data('product').name, +$(this).val()); | |
| } | |
| }, 'select.itemCount'); | |
| $buy.click(function() { | |
| return controller.onBuy(); | |
| }); | |
| model.set('golds', 1000); | |
| model.set('greeting', 'へいいらっしゃい!'); | |
| model.add('products', { | |
| name: 'ポーション', | |
| price: 50 | |
| }); | |
| model.add('products', { | |
| name: 'ハイポーション', | |
| price: 250 | |
| }); | |
| model.add('products', { | |
| name: 'エーテル', | |
| price: 500 | |
| }); | |
| return model.add('products', { | |
| name: 'フェニックスの尾', | |
| price: 1000 | |
| }); | |
| }, | |
| onItemCountChange: function(itemName, count) { | |
| var _this = this; | |
| return whileEvent(function() { | |
| return model.put('cart', itemName, count); | |
| }); | |
| }, | |
| onBuy: function() { | |
| var _this = this; | |
| return whileEvent(function() { | |
| return model.buy(); | |
| }); | |
| } | |
| }; | |
| setTimeout((function() { | |
| return model.add('products', { | |
| name: '10秒滞在記念アイテム', | |
| price: 200 | |
| }); | |
| }), 10 * 1000); | |
| setTimeout((function() { | |
| return model.add('products', { | |
| name: '50秒滞在記念アイテム', | |
| price: 1400 | |
| }); | |
| }), 50 * 1000); | |
| $frame.find('.make_money').click(function() { | |
| return model.set('golds', (model.get('golds')) + 1000); | |
| }); | |
| return controller.init(); | |
| }); | |
| }).call(this); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>My MVC notions</title> | |
| <style> | |
| .show_case{ border: 1px solid #ccc ; padding: 1em; margin-bottom:1em; } | |
| #simple_case .input_history{ max-height:10em; overflow:scroll; border: 1px solid #666; } | |
| </style> | |
| </head> | |
| <body> | |
| <h1>MVCってなんだろう?</h1> | |
| <section id="simple_case"> | |
| <h2>シンプルなケース</h2> | |
| <ul> | |
| <li>オブジェクトはモデルとビューとコントローラと役割分担している</li> | |
| <li>モデルを更新するとビューが追従して、モデルの値を参照しながら自分を更新する</li> | |
| <li>ビューの修正はコントローラに伝わる → コントローラはモデルの操作メソッドを呼ぶ</li> | |
| </ul> | |
| <section id="simple_case" class="show_case"> | |
| <h3>実装例 〜 BMI計算機</h3> | |
| <dl> | |
| <dt>モデル</dt> | |
| <dd>体重、身長、入力履歴、BMI計算、適正体重計算、診断コメント</dd> | |
| <dt>コントローラ</dt> | |
| <dd>コントローラ</dd> | |
| <dt>ビュー</dt> | |
| <dd>身長入力、体重入力、入力履歴表示、BMI表示、適正体重表示、診断コメント</dd> | |
| </dl> | |
| <p> | |
| <label> | |
| 身長入力: | |
| <input class='height'/>cm | |
| </label> | |
| <label> | |
| 体重入力: | |
| <input class="weight"/>kg | |
| </label> | |
| </p> | |
| <p> | |
| あなたのBMIは<span class="bmi">○○</span>です。 | |
| 適切体重は<span class="best_weight">☓XX</span>kgです。 | |
| <span class="bmi_message"></span> | |
| </p> | |
| <p> | |
| <label> | |
| <input class="manipulate_model_randomly" type="checkbox"/> 適当にモデルをいじくりまわす | |
| </label> | |
| <label> | |
| <input class="operate_view_randomly" type="checkbox"/> 適当にビューを操作させてみる | |
| </label> | |
| </p> | |
| <p> | |
| 入力履歴: | |
| </p> | |
| <ul class="input_history"> | |
| </ul> | |
| </section> | |
| <section id="itemshop" class="show_case"> | |
| <h3>実装例 〜 アイテム購入画面</h3> | |
| <dl> | |
| <dt>モデル</dt> | |
| <dd>販売アイテム、所持ゴールド、アイテム購入予定表、アイテム購入予定額計算、道具袋</dd> | |
| <dt>コントローラ</dt> | |
| <dd>コントローラ</dd> | |
| <dt>ビュー</dt> | |
| <dd>あいさつ、所持金、アイテム購入表、購入総額、購入ボタン、道具袋</dd> | |
| </dl> | |
| <p> | |
| 店主「<span class="greeting"></span>」 | |
| </p> | |
| <table border="1"> | |
| <thead> | |
| <tr> | |
| <td>アイテム名</td><td>値段</td><td>購入個数</td> | |
| </tr> | |
| </thead> | |
| <tbody class="products"> | |
| </tbody> | |
| </table> | |
| <p> | |
| 購入総額:<span class="cart_total">0</span>ゴールド / 所持金:<span class="golds">0</span>ゴールド | |
| <input type='button' class='buy' value="購入する" > | |
| </p> | |
| <p> | |
| 道具袋: | |
| </p> | |
| <pre class="item_bag"> | |
| </pre> | |
| <p> | |
| <input type='button' class='make_money' value="1000ゴールド手に入 れる" > | |
| </p> | |
| </section> | |
| </section> | |
| <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> | |
| <script src="simple_case.js"></script> | |
| <script src="itemshop.js"></script> | |
| <script src="simple_chat.js"></script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| global = @ | |
| $ -> | |
| # シンプルなケース | |
| calculate_bmi = (h, w) -> Math.floor( 1000000 * w / h / h + 0.5) / 100 | |
| calculate_best_weight = (h) -> Math.floor( 22 * h * h / 100 + 0.5 ) / 100 | |
| bmi_message = (bmi) -> | |
| if bmi < 18.5 | |
| '痩せすぎぃ' | |
| else if bmi < 25 | |
| '普通すぎぃ' | |
| else if bmi < 30 | |
| 'ぽっちゃりすぎぃ' | |
| else if bmi < 35 | |
| 'デブすぎぃ' | |
| else | |
| '病院行け' | |
| # モデル | |
| model = | |
| height: 160 | |
| weight: 50 | |
| events: {} | |
| bmi: -> calculate_bmi(@height, @weight) | |
| bestWeight: -> calculate_best_weight(@height) | |
| bmiMessage: -> bmi_message @bmi() | |
| inputHistory: [] | |
| addInputHistory: (history) -> | |
| @inputHistory.shift() if(@inputHistory.length > 100) | |
| @inputHistory.push history | |
| @fire 'inputHistory' | |
| get: (property) -> @[property] | |
| set: (property, value) -> | |
| console.log "Property #{property} has been changed: #{@[property]} => #{value}" | |
| @[property] = value | |
| @fire property | |
| fire: (property) -> | |
| for fn in @events[property] | |
| fn() | |
| on: (property, fn) -> | |
| (@events[property] ?= []).push fn | |
| # もっとモデル追加してもいいかも | |
| global.simple_model = model | |
| # ビュー | |
| $frame = $('#simple_case') | |
| $height = $frame.find('.height') | |
| $weight = $frame.find('.weight') | |
| $bmi = $frame.find('.bmi') | |
| $best_weight = $frame.find('.best_weight') | |
| $bmi_message = $frame.find('.bmi_message') | |
| $input_history = $frame.find('.input_history') | |
| # (無限ループ対策 モデル変更 → ビュー変更 → モデル変更 ... の無限ループ回避) | |
| whileEventProcess = false | |
| whileEvent = (fn) -> | |
| try | |
| whileEventProcess = true | |
| fn() | |
| finally | |
| whileEventProcess = false | |
| # コントローラ | |
| controller = | |
| init: -> | |
| modifyBmiView = -> | |
| $bmi.text model.bmi() | |
| $bmi_message.text model.bmiMessage() | |
| $best_weight.text model.bestWeight() | |
| # モデル -> ビュー | |
| model.on 'height', modifyBmiView | |
| model.on 'weight', modifyBmiView | |
| model.on 'height', -> | |
| $height.val(model.get('height')) unless whileEventProcess | |
| model.on 'weight', -> | |
| $weight.val(model.get('weight')) unless whileEventProcess | |
| model.on 'inputHistory', -> | |
| $li = ( $('<li>').text(history) for history in model.get('inputHistory') ) | |
| $li.reverse() | |
| $input_history.html('').append $li... | |
| # ビュー -> コントローラ | |
| $height.on 'change', @onChangeHeight | |
| $weight.on 'change', @onChangeWeight | |
| model.set 'height', 180 | |
| model.set 'weight', 70 | |
| onChangeHeight: -> | |
| whileEvent -> | |
| # コントローラからモデルを操作 | |
| height = $height.val() | |
| model.set 'height', + height | |
| model.addInputHistory "身長 #{height} を入力。" | |
| onChangeWeight: -> | |
| whileEvent -> | |
| # コントローラからモデルを操作 | |
| weight = $weight.val() | |
| model.set 'weight', + weight | |
| model.addInputHistory "体重 #{weight} を入力。" | |
| controller.init() | |
| # 適当にモデルをいじくりまわす機能(モデルの変更にいろいろ連動することがわかる) | |
| ranged_random = (from, to) -> Math.floor( from + ( Math.random() * (to - from) )) | |
| $manipulate_model_randomly = $frame.find('.manipulate_model_randomly') | |
| $manipulate_model_randomly.change -> | |
| activated = => $(@).is(':checked') | |
| manipulateModel = (prop, gen) -> | |
| if activated() | |
| model.set prop, gen() | |
| setTimeout (-> manipulateModel prop, gen), ranged_random(0, 1000) | |
| manipulateModel 'height', -> ranged_random(100, 200) | |
| manipulateModel 'weight', -> ranged_random(20, 100) | |
| $operate_view_randomly = $frame.find('.operate_view_randomly') | |
| $operate_view_randomly.change -> | |
| activated = => $(@).is(':checked') | |
| operateView = ($view) -> | |
| if activated() | |
| $view.val (1 + ( + $view.val())) | |
| $view.change() | |
| setTimeout (-> operateView $view), ranged_random(0, 100) | |
| operateView $height | |
| operateView $weight | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Generated by CoffeeScript 1.6.3 | |
| (function() { | |
| var global; | |
| global = this; | |
| $(function() { | |
| var $best_weight, $bmi, $bmi_message, $frame, $height, $input_history, $manipulate_model_randomly, $operate_view_randomly, $weight, bmi_message, calculate_best_weight, calculate_bmi, controller, model, ranged_random, whileEvent, whileEventProcess; | |
| calculate_bmi = function(h, w) { | |
| return Math.floor(1000000 * w / h / h + 0.5) / 100; | |
| }; | |
| calculate_best_weight = function(h) { | |
| return Math.floor(22 * h * h / 100 + 0.5) / 100; | |
| }; | |
| bmi_message = function(bmi) { | |
| if (bmi < 18.5) { | |
| return '痩せすぎぃ'; | |
| } else if (bmi < 25) { | |
| return '普通すぎぃ'; | |
| } else if (bmi < 30) { | |
| return 'ぽっちゃりすぎぃ'; | |
| } else if (bmi < 35) { | |
| return 'デブすぎぃ'; | |
| } else { | |
| return '病院行け'; | |
| } | |
| }; | |
| model = { | |
| height: 160, | |
| weight: 50, | |
| events: {}, | |
| bmi: function() { | |
| return calculate_bmi(this.height, this.weight); | |
| }, | |
| bestWeight: function() { | |
| return calculate_best_weight(this.height); | |
| }, | |
| bmiMessage: function() { | |
| return bmi_message(this.bmi()); | |
| }, | |
| inputHistory: [], | |
| addInputHistory: function(history) { | |
| if (this.inputHistory.length > 100) { | |
| this.inputHistory.shift(); | |
| } | |
| this.inputHistory.push(history); | |
| return this.fire('inputHistory'); | |
| }, | |
| get: function(property) { | |
| return this[property]; | |
| }, | |
| set: function(property, value) { | |
| console.log("Property " + property + " has been changed: " + this[property] + " => " + value); | |
| this[property] = value; | |
| return this.fire(property); | |
| }, | |
| fire: function(property) { | |
| var fn, _i, _len, _ref, _results; | |
| _ref = this.events[property]; | |
| _results = []; | |
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
| fn = _ref[_i]; | |
| _results.push(fn()); | |
| } | |
| return _results; | |
| }, | |
| on: function(property, fn) { | |
| var _base; | |
| return ((_base = this.events)[property] != null ? (_base = this.events)[property] : _base[property] = []).push(fn); | |
| } | |
| }; | |
| global.simple_model = model; | |
| $frame = $('#simple_case'); | |
| $height = $frame.find('.height'); | |
| $weight = $frame.find('.weight'); | |
| $bmi = $frame.find('.bmi'); | |
| $best_weight = $frame.find('.best_weight'); | |
| $bmi_message = $frame.find('.bmi_message'); | |
| $input_history = $frame.find('.input_history'); | |
| whileEventProcess = false; | |
| whileEvent = function(fn) { | |
| try { | |
| whileEventProcess = true; | |
| return fn(); | |
| } finally { | |
| whileEventProcess = false; | |
| } | |
| }; | |
| controller = { | |
| init: function() { | |
| var modifyBmiView; | |
| modifyBmiView = function() { | |
| $bmi.text(model.bmi()); | |
| $bmi_message.text(model.bmiMessage()); | |
| return $best_weight.text(model.bestWeight()); | |
| }; | |
| model.on('height', modifyBmiView); | |
| model.on('weight', modifyBmiView); | |
| model.on('height', function() { | |
| if (!whileEventProcess) { | |
| return $height.val(model.get('height')); | |
| } | |
| }); | |
| model.on('weight', function() { | |
| if (!whileEventProcess) { | |
| return $weight.val(model.get('weight')); | |
| } | |
| }); | |
| model.on('inputHistory', function() { | |
| var $li, history, _ref; | |
| $li = (function() { | |
| var _i, _len, _ref, _results; | |
| _ref = model.get('inputHistory'); | |
| _results = []; | |
| for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |
| history = _ref[_i]; | |
| _results.push($('<li>').text(history)); | |
| } | |
| return _results; | |
| })(); | |
| $li.reverse(); | |
| return (_ref = $input_history.html('')).append.apply(_ref, $li); | |
| }); | |
| $height.on('change', this.onChangeHeight); | |
| $weight.on('change', this.onChangeWeight); | |
| model.set('height', 180); | |
| return model.set('weight', 70); | |
| }, | |
| onChangeHeight: function() { | |
| return whileEvent(function() { | |
| var height; | |
| height = $height.val(); | |
| model.set('height', +height); | |
| return model.addInputHistory("身長 " + height + " を入力。"); | |
| }); | |
| }, | |
| onChangeWeight: function() { | |
| return whileEvent(function() { | |
| var weight; | |
| weight = $weight.val(); | |
| model.set('weight', +weight); | |
| return model.addInputHistory("体重 " + weight + " を入力。"); | |
| }); | |
| } | |
| }; | |
| controller.init(); | |
| ranged_random = function(from, to) { | |
| return Math.floor(from + (Math.random() * (to - from))); | |
| }; | |
| $manipulate_model_randomly = $frame.find('.manipulate_model_randomly'); | |
| $manipulate_model_randomly.change(function() { | |
| var activated, manipulateModel, | |
| _this = this; | |
| activated = function() { | |
| return $(_this).is(':checked'); | |
| }; | |
| manipulateModel = function(prop, gen) { | |
| if (activated()) { | |
| model.set(prop, gen()); | |
| return setTimeout((function() { | |
| return manipulateModel(prop, gen); | |
| }), ranged_random(0, 1000)); | |
| } | |
| }; | |
| manipulateModel('height', function() { | |
| return ranged_random(100, 200); | |
| }); | |
| return manipulateModel('weight', function() { | |
| return ranged_random(20, 100); | |
| }); | |
| }); | |
| $operate_view_randomly = $frame.find('.operate_view_randomly'); | |
| return $operate_view_randomly.change(function() { | |
| var activated, operateView, | |
| _this = this; | |
| activated = function() { | |
| return $(_this).is(':checked'); | |
| }; | |
| operateView = function($view) { | |
| if (activated()) { | |
| $view.val(1 + (+$view.val())); | |
| $view.change(); | |
| return setTimeout((function() { | |
| return operateView($view); | |
| }), ranged_random(0, 100)); | |
| } | |
| }; | |
| operateView($height); | |
| return operateView($weight); | |
| }); | |
| }); | |
| }).call(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment