본문 바로가기

Javascript/Knockout

The "click" binding

Purpose(목적)

click 바인딩은 이벤트 핸들러를 추가하여 해당 DOM의 요소가 클릭될때 선택된 자바스크립트를 호출한다. button,input, a 요소들과 같이 일반적으로 사용된다. 그라나 실제적으로 어떤 보여지는 DOM요소들과 같이 작동한다.

Example

<div>
    You've clicked <span data-bind="text: numberOfClicks"></span> times
    <button data-bind="click: incrementClickCounter">Click me</button>
</div>
 
<script type="text/javascript">
    var viewModel = {
        numberOfClicks : ko.observable(0),
        incrementClickCounter : function() {
            var previousCount = this.numberOfClicks();
            this.numberOfClicks(previousCount + 1);
        }
    };
</script>

매번 버튼을 클릭할때마다 viewModel에 있는 incrementClickCounter()가 호출될것이다. view model의 상태가 바뀌게되면 UI요소들도 업데이트 된다.

Parameters

  • Main parameter(주 파라미터)

    clock 이벤트에 바인딩할 function

    여러분은 어떤 Javascript 함수도 참조할수 있습니다. 이 말은 view model에서 꼭 함수일 필요가 없다는 뜻입니다. 여러분은 어떤 객체의 함수를 다음과 같이 작성하여 참조할 수 있습니다. click: someObject.someFunction.

  • Additional parameters(추가 파라미터)

    • None(없음)

Note 1: 여러분의 핸들러 함수에 현재 아이템을 파라미터로 보내기

여러분이 핸들러를 호출할때 Kockout은 현재의 view model값을 첫 파라미터로 보냅니다.  콜렉션으로 특정 부분을 렌더링할때 어떤 UI에서 클릭이 되었는지 알아야 할때 이 기능은 매우 유용합니다. 예를 들면 아래와 같습니다:

<ul data-bind="foreach: places">
    <li>
        <span data-bind="text: $data"></span>
        <button data-bind="click: $parent.removePlace">Remove</button>
    </li>
</ul>
 
 <script type="text/javascript">
     function MyViewModel() {
         var self = this;
         self.places = ko.observableArray(['London', 'Paris', 'Tokyo']);
 
         // The current item will be passed as the first parameter, so we know which place to remove
         self.removePlace = function(place) {
             self.places.remove(place)
         }
     }
     ko.applyBindings(new MyViewModel());
</script>

위의 예제에서는 두가지 주요사항이 있습니다.:

  • 여러분이 nested된 바인딩 문맥에 있을때 예를 들어 foreach 또는 with 블록에 있을때 그러나 여러분의 핸들러 함수는 root view model또는 다른 부모 문맥에 있을때 여러분은 $parent또는 $root 키워드를 사용하여 핸들러 함수를 불러올수 있습니다.
  • viewmodel에서 self는 this의 닉네임으로 자주 사용됩니다.  이렇게 함으로써 재정의 된 this와 함께 일어나는 문제들을 피할수 있습니다.

Note 2: event 객체에 접근하기 또는 추가 파라미터 넘기기

여러분은 때로 클릭했을 때 DOM이벤트 객체에 접근해야할 필요가 있습니다. Knockout은 여러분의 함수에 두번째 파라미터로 event를 보내줍니다. 예를 들면 아래와 같습니다:

<button data-bind="click: myFunction">
    Click me
</button>
 
 <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로 랩핑하면됩니다. 예를 들면 아래와 같습니다.:

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

이제 KO는 데이터와 이벤트 객체를 여러분의 literal 함수에 넘길것입니다. 

다른 방법으로는 bind 함수를 사용하는 것입니다. 사용법은 아래와같습니다:

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

Note 3: default click action 허용하기

기본적으로 Kockout은 어떤한 기본 action으로 부터 click event를 방지합니다. 이 말은 a 태그에 click 이벤트를 바인딩 했다는 말입니다.  예를 들어 a 태그를 클릭했을때 href는 작동하지 않는다는 말입니다. 이러한 기능은 click바인딩을 사용할때 매우 유용합니다.

그러나 여러분이 default 클릭 action을 허용하고 싶다면 단순하게 click핸들러 함수에 return true를 작성하여 주세요

Note 4: bubbling방지하기

기본적으로 Kockout은 bubblling을 허용합니다. 예를 들어 한 요소와 그것의 부모 요소에 click이벤트 핸들러가 있다면 자식의 요소를 클릭했을때 부모의 click이벤트 핸들러도 호출되게 됩니다. 필요하다면 여러분은 이러한 bubbling을 clickBubble :false 를 사용하여 막을수 있습니다.

<div data-bind="click: myDivHandler">
    <button data-bind="click: myButtonHandler, clickBubble: false">
        Click me
    </button>
</div>

일반적으로 위의 예에서  myButtonHandler 가 처음으로 후출되고 그다음에 myDivHandler가 호출됩니다. 그러나 clickBubblefalse로 추가 되었기 때문에 버블링은 일어나지 않습니다.

필요한 라이브러리

Knockout Core library