본문 바로가기

Javascript/Knockout

The "event" binding


Purpose(목적)

event 바인딩은 특정한 이벤트에 이벤트 핸들러를 추가시켜준다. 그래서 이벤트가 발생할대 여러분이 선택한 Javascript함수가 호출되게 된다. 이벤트 바인딩은 다음과 같이 어떤 이벤트에도 적용될수 있다. (keypressmouseover , mouseout)

Example

<div>
    <div data-bind="event: { mouseover: enableDetails, mouseout: disableDetails }">
        Mouse over me
    </div>
    <div data-bind="visible: detailsEnabled">
        Details
    </div>
</div>
 
<script type="text/javascript">
    var viewModel = {
        detailsEnabled: ko.observable(false),
        enableDetails: function() {
            this.detailsEnabled(true);
        },
        disableDetails: function() {
            this.detailsEnabled(false);
        }
    };
    ko.applyBindings(viewModel);
</script>

지금 여러분의 마우스 포인터를 첫번째 엘러먼터에 올려놨다가 내려놔 보십시오 그러면 view model에 있는 detailsEnabled observable이 호출되어 토글이 될것입니다. 두번째 엘러먼트는 detailsEnabled값이 바뀌면서 보여지고 안보여지고 할것입니다.

Parameters(파라머터)

  • Main parameter(주 파라미터)

    여러분은 반드시 .event 이름에 해당 javascript 객체를 넘겨줘야합니다. 그리고 해당 이벤드에 바인딩하고 싶은 함수값을 넣어줍니다.

    여러분은 어떠한 Javascript함수도 참조할수 있습니다. - 이 말은 즉 꼭 함수일 필요는 없다는 얘기입니다. 여러분은 다음과 같이 작성할 수 있습니다. event { mouseover: someObject.someFunction }.

  • Additional parameters(추가 파라미터)

    • None(없음)

Note 1: 현재 아이템을 핸들러의 파라미터로 넘기기

핸들러를 호출할때, Kockout은 핸제 model값을 첫번째 파라미터로 넘겨줍니다. Collection에서 각 아이템에 대한 UI를 렌더링할때 매우 유용합니다. 그리고 여러분은 어떤 아이템에 이벤트가 바인딩 되어있는지 알아야합니다. 아래의 예를 보십시오

<ul data-bind="foreach: places">
    <li data-bind="text: $data, event: { mouseover: $parent.logMouseOver }"> </li>
</ul>
<p>You seem to be interested in: <span data-bind="text: lastInterest"> </span></p>
 
 <script type="text/javascript">
     function MyViewModel() {
         var self = this;
         self.lastInterest = ko.observable();
         self.places = ko.observableArray(['London', 'Paris', 'Tokyo']);
 
         // The current item will be passed as the first parameter, so we know which place was hovered over
         self.logMouseOver = function(place) {
             self.lastInterest(place);
         }
     }
     ko.applyBindings(new MyViewModel());
</script>

위의 예에서 2가지 주목해야 할 점이 있습니다.:

  • nested binding context 바인딩 안에 있을때 , 예를 들어 여러분이 foreah또는 with블록 안에 있고 root viewmodel또는 다른 parent context에 없을때 여러분은 $parent또는 $root라는 접두어를 붙여서 프로퍼티에 접근할 수 있습니다.
  • viewmodel에서 self라는 변수는 this의 별칭으로 자주 사용됩니다.  이렇게 하면 어떤 this와 함께 일어날수 있는 문제들을 피할수 있습니다. 

Note 2: Event객체 접근과 파라미터 넘기기

어떤 경우 여러분은 DOM event객체에 접근해야할때가 있을겁니다. Kockout은 두번째 파라미터로 event객체를 넘겨줍니다. 예는 아래와 같습니다.:

<div data-bind="event: { mouseover: myFunction }">
    Mouse over me
</div>
 
 <script type="text/javascript">
    var viewModel = {
        myFunction: function(data, event) {
            if (event.shiftKey) {
                //do something different when user has shift key down
            } else {
                //do normal action
            }
        }
    };
    ko.applyBindings(viewModel);
</script>

만약 여러분이 더 많은 파라미터를 넘겨주고 싶으면 한가지 방법으로 여러분의 핸들러를 함수 literal로 아래와 같이 만들어 주면 됩니다.:

<div data-bind="event: { mouseover: function(data, event) { myFunction('param1', 'param2', data, event) } }">
    Mouse over me
</div>

이제 KO는 여러분의 literal 함수에 event를 넘겨줄겁니다.

다른방법으로 여러분은 함수 literal에 bind를 사용할수있습니다. 이 bind함수는 특별한 파라미터들을 넘겨줄수 있습니다. 예제는 아래와 같습니다.

<button data-bind="event: { mouseover: myFunction.bind($data, 'param1', 'param2') }">
    Click me
</button>

Note 3: 기본 action허용하기

기본적으로 Kockout은 어떤 기본 action으로 부터 이벤트를 방지합니다. 예를들어 여러분이 keypress 이벤를 input에 바인딩하고 keypress를 누르면 브라우저는 단지 한번만 여러분이 바인딩한 이벤트 핸들러만 호출합니다. 다른 이벤트들은 호출되지 않는다는 말이지요 만약 굳이 하고 싶으면 click 바인딩에서 소개했던 것과 같이 하면 됩니다.

Note 4: 버블링 방지

기본적으로 Kockout은  버블링을 지원합니다:

<div data-bind="event: { mouseover: myDivHandler }">
    <button data-bind="event: { mouseover: myButtonHandler }, mouseoverBubble: false">
        Click me
    </button>
</div>

정상적으로 myButtonHandler의 경우 처음에 호출되고 그다음으로 myDivHandler가 호출됩니다. 

필요한 라이브러리

Knockout Core library.