본문 바로가기

Dev.FrontEnd/JavaScript

#JavaScript MVC 모델 연습 - spinbox

#JavaScript로 알아보는 MVC 모델


웹 프로그래밍에서 가장 중요한 개념 중 하나인 MVC 모델에 대해서 알아보도록 하자.

최근 들어서 서버 사이드 렌더링 말고도,

클라이언트 사이드 렌더링과 관련된 프레임워크들이 많이 등장하고 있다. (Angular, Ember, 등)

JavaScript로 MVC는 어떻게 설계하는가?

간단한 예제인 SpinBox sample을 통해서 MVC 구조에 대해 간단하게 알아보자.

>> MVC 모델이란? >>



1단계. JavaScript의 작동을 확인할 기본적인 html 구조를 잡자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="style.css">
    <title>spinbox MVC</title>
</head>
<body>
    <h1 id="h">Spinbox</h1>
    <form>
        <div class="form">
            <input type="text" class="form-control result">
            <button type="button" class="btn-increase">+</button>
            <button type="button" class="btn-decrease">-</button>
        </div>
    </form>
    <script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"></script>
    <script src="/spinbox/spinbox.controller.js"></script>
    <script src="/spinbox/spinbox.model.js"></script>
    <script src="/spinbox/spinbox.view.js"></script>
    <script src="app.js"></script>
</body>
</html>
 
cs


html에서 주의할 점 중 하나는,

script 태그를 통해서 자바스크립트를 읽어오는 부분이다.

app.js파일이 가장 마지막에 연결되어야 한다.

각 파일에 대한 코드를 보면 이해가 될 것이다.



2. 자바스크립트 파일을 생성하자.

model.js, view.js, controller.js, app.js

각각의 model, view, controller는 Module Pattern을 통해 만든다.

Module Pattern이란 즉시 실행 함수( Immediately Invoked Function )에

this 인자를 넘겨주고 함수 내부에서 exports란 인자로 접근할 수 있는 패턴을 말한다.

>> 모듈 패턴 ( Module Pattern ) 에 대한 포스팅 >>

model.js code>

1
2
3
4
5
6
7
(function(exports){
    function SpinboxModel(value){
 
    }
     exports.SpinboxModel = SpinboxModel;
 
})(this);
cs


view.js code>

1
2
3
4
5
6
7
(function(exports){
    function SpinboxView(){
 
    }
     exports.SpinboxView = SpinboxView;
 
})(this);
cs


controller.js code>

1
2
3
4
5
6
7
(function(exports){
    function SpinboxController(){
 
    }
     exports.SpinboxController = SpinboxController;
 
})(this);
cs


=> 모두 동일한 구조를 취하고 있다.

여기서 this는 window 객체를 가리킨다.

각각의 Module에서 생성자 함수를 작성하고, exports 인자를 통해 window 객체에 추가한다.

tip> 생성자 함수의 첫글자는 Upper case로 작성하는 것이 Convention이다.



2. 각각의 생성자 함수를 구현하자.

model.js code>
1
2
3
4
function SpinboxModel(value) {
    value = value || 100;
    this.data = value;
}
cs
=> 데이터를 다루는 Model 에는 value 값을 저장하고 있게 한다.
그리고 그 value ‘값'을 window 에 data라는 객체로 추가해준다. 


view.js code>
1
function SpinboxView() {}
cs
=> View는 특별한 인스턴스를 포함하고 있을 필요가 없다.


controller.js code>
1
2
3
4
5
6
7
8
9
function SpinboxController() {
    this.spinboxModel = new SpinboxModel();
    this.spinboxView = new SpinboxView();
 
    this.spinboxView.render(this.spinboxModel.getData());
 
    $(".btn-increase").on("click", $.proxy(this.onClickIncrease, this));
    $(".btn-decrease").on("click", $.proxy(this.onClickDecrease, this));
}
cs

=> controller의 역할이 model 과 view 를 중개하는 역할이므로,
생성자 함수에 model 과 view 를 생성하는 코드를 작성한다.
그리고 클라이언트로부터 이벤트를 받는 역할이므로, 이벤트를 달아주자.




3. 각각의 메소드를 구현하자.

view는 화면을 그리는 역할을 하므로 render라는 메소드를 구현하면 되겠다.

model은 data를 get하고 manipulate하는(increase, decrease) 메소드를 구현하면 될 것이다.
prototype을 통해 메소드를 정의해주게 되면 불필요한 메모리 낭비를 방지할 수 있다.


Model.js code>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SpinboxModel.prototype = {
    increase : function(value){
        value = value || 1;
        this.data += value;
        return this.data;
    },
    decrease : function(value){
        value = value || 1;
        this.data -= value;
        return this.data;
    },
    getData : function(){
        return this.data;
    }
};
cs


View.js code>
1
2
3
4
5
SpinboxView.prototype = {
     render : function(value) {
          $('.result').val(value);
     }
};
cs


Controller.js code>
1
2
3
4
5
6
7
8
9
10
SpinboxController.prototype = {
    onClickIncrease: function(){
        this.spinboxModel.increase();
        this.spinboxView.render(this.spinboxModel.getData());
    },
    onClickDecrease: function(){
        this.spinboxModel.decrease();
        this.spinboxView.render(this.spinboxModel.getData());
    }
};
cs

app.js code>

1
2
3
4
5
window.addEventListener('load'function(){
   "use strict";
   console.log('app.js execute!');
   new SpinboxController();
});
cs


자바스크립트에 대한 기본적인 지식이 부족하다면 다음 링크를 참고해도 좋을 것 같다.

http://jstherightway.org/ko-kr/#patterns


End