Skip to content

Instantly share code, notes, and snippets.

@tkd55
Created February 18, 2015 05:58
Show Gist options
  • Save tkd55/0764e04c71a4ec053238 to your computer and use it in GitHub Desktop.
Save tkd55/0764e04c71a4ec053238 to your computer and use it in GitHub Desktop.
JavaScript Design Pattern MVVM
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div id="first-view">
        <h2>First View</h2>
        <div id="show-area">1</div>
        <button class='add-btn' data-bind="click: add">プラス</button>
        <button class='remove−btn'>マイナス</button>
        <button class='next-btn'>次へ</button>
    </div>
    <div id="second-view" style="display:none">
        <h2>Second View</h2>
        <button class='return-btn'>戻る</button>
    </div>
</body>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    ;(function(w, d, $){

        // observeのお試し
        // Object.observe(obj, callback);
        // function callback(){
        //     change.forEach(function(change){
        //         console.log(change.type);       // changeの種類
        //         console.log(change.name);       // プロパティ名
        //         console.log(change.oldValue);   // 以前の値
        //         console.log(change.object);     // 監視しているオブジェクト
        //     });
        // }

        $(function(){
            var viewModel = new ViewModel();
            var view = new View(viewModel);
            view.init();
        });

        var View = (function(w, d, $){
            function View(aViewModel){
                View.prototype.viewModel = aViewModel;
            }
            View.prototype.init = function(){
                this.showContents('first');
            };

            View.prototype.showContents = function(aType){
                switch(aType){
                    case 'first':
                        var firstView = new FirstView(this.viewModel);
                        firstView.init();
                        break;
                    case 'second':
                        var secondView = new SecondView(this.viewModel);
                        secondView.init();
                        break;
                    default:
                        break;
                }
            };

            return View;
        })(window, document, window.jQuery);




        var FirstView = (function(w, d, $){
            function FirstView(aViewModel){
                this.super = View.prototype;
                this.viewModel = aViewModel;
            }

            FirstView.prototype.init = function(){
                var self = this;
                $('.add-btn').on('click', function(evt){
                    self.viewModel.add();
                });

                $('.remove−btn').on('click', function(evt){
                    self.viewModel.remove();
                });

                $('.next-btn').on('click', function(evt){
                    self.viewModel.changeScene('second', self.super.showContents, self.super);
                });
                this.viewModel.setObserve(this.show);

                this.create();
            };

            FirstView.prototype.create = function(){
                $('#first-view').show();
                $('#second-view').hide();
            }

            FirstView.prototype.show = function(change){
                change.forEach(function(change){
                    console.log(change.type);       // changeの種類
                    console.log(change.name);       // プロパティ名
                    console.log(change.oldValue);   // 以前の値
                    console.log(change.object);     // 監視しているオブジェクト
                    $('#show-area').text(change.object.num);
                }, this);
            };

            return FirstView;
        })(window, document, window.jQuery);




        var SecondView = (function(w, d, $){
            function SecondView(aViewModel){
                this.super = View.prototype;
                this.viewModel = aViewModel;
            }
            // SecondView.prototype = Object.create(View.prototype);
            // SecondView.prototype.constructor = SecondView;
    
            SecondView.prototype.init = function(){
                var self = this;
                $('.return-btn').on('click', function(evt){
                    self.viewModel.changeScene('first', self.super.showContents, self.super);
                });
                this.create();
            };

            SecondView.prototype.create = function(){
                $('#first-view').hide();
                $('#second-view').show();
            };

            return SecondView;
        })(window, document, window.jQuery);



        var ViewModel = (function(w, d, $){
            function ViewModel(aMessenger){
                this.messenger = aMessenger;
                this.dataObj = {num: 1};
            }

            ViewModel.prototype.setObserve = function(callbackFunc){
                // コールバックの登録
                Object.observe(this.dataObj, callbackFunc);
            };

            ViewModel.prototype.add = function(){
                this.dataObj.num++;
            };

            ViewModel.prototype.remove = function(){
                this.dataObj.num--;
            };

            ViewModel.prototype.changeScene = function(aSceneName, callbackFunc, caller){
                callbackFunc.call(caller, aSceneName);
            };

            return ViewModel;

            // defineProperties
            // 1 つ以上のプロパティをオブジェクトに追加したり既存のプロパティの属性を変更する
            // Object.defineProperties(obj, {a: {enumerable: false}});
        })(window, document, window.jQuery);


        // var Model = (function(w, d, $){
        //     function Model(){
        //         this.scene = '';
        //     }
        //     Model.prototype.setObserve = function(callbackFunc){
        //         // コールバックの登録
        //         Object.observe(this.scene, callbackFunc);
        //     };
        //     Model.prototype.changeScene = function(aSceneKind){
        //         this.scene = aSceneKind;
        //     };
        //     return Model;
        // })(window, document, window.jQuery);

    })(window, document, window.jQuery);
    </script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment