listview에서 itemclick이벤트가 아닌 특정 object의 onClick 이벤트 처리할 때...

listview에서 itemclick이벤트가 아닌 특정 object의 onClick 이벤트 처리가 필요할 때 있죠.

<ItemTemplate name="rankRow" class="rankRow" >
  <View bindId="root" class="rankRowBox">
    ...
        <View class="rankTextWrap0" onClick="onClickRank0">
          <Label bindId="rankText0" class="rankText0" />
        </View>
    ...
    </View>
</ItemTemplate>

이러면 안드로이드에서는 cancelBuble만 처리해줘도, itemclick이벤트가 발생하지 않습니다.

하지만 iOS에서는 itemclick이벤트가 먼저 발생합니다. cancelBuble이고 뭐고 자비가 없죠…

iOS에서 itemclick 이벤트를 막으려면 2가지를 처리해줘야 합니다.

1) View가 아닌 Label에 onClick 이벤트 걸기

<ItemTemplate name="rankRow" class="rankRow" >
  <View bindId="root" class="rankRowBox">
    ...
        <View class="rankTextWrap0">
          <Label bindId="rankText0" class="rankText0" onClick="onClickRank0" />
        </View>
    ...
    </View>
</ItemTemplate>

그러면 Label이 아닌 ImageView는 어쩔거냐?
Label을 ImageView위에 띄워주면 됩니다. (ImageView는 View와 동일하게 동작해버립니다.)

<ImageView bindId="rank0Btn" class="rank0Btn" />
<Label class="rank0Btn" onClick="onClickRank0"/>

(zIndex를 주거나 ImageView 다음에 배치합니다.)

2) itemclick 이벤트 껐다 켜기

Label의 경우 itemclick 이벤트가 먼저 발생하진 않지만 발생하긴 합니다. 그래서 껐다 켜줘야 합니다-_ -;

function onClickRank0(e) {
  e.cancelBubble = true;
  
  OS_IOS && $.trigger('remove:itemclick');
  $.trigger('click:rank0', e);
  OS_IOS && $.trigger('add:itemclick');
}

var $observer =  _.extend({}, Backbone.Events);

$observer.listenTo($, 'remove:itemclick', function () {
  $.listView.removeEventListener("itemclick", CTX.onClickRow);
});
$observer.listenTo($, 'add:itemclick', function () {
  $.listView.addEventListener("itemclick", CTX.onClickRow);
});
$observer.listenTo($, 'click:rank0', CTX.onClickRank0);

(이벤트 루프의 처리 순서를 항상 보장하기 위해서 하나의 Backbone객체로 수신하고 trigger로 발생 시킵니다.

마지막팁으로 close 이벤트에서 이벤트 리쓰너를 정리해주면 메모리 관리에 도움이 됩니다.

$.getView().addEventListener('close', function() {
    $observer.stopListening();
    $.destroy();
});

요새 앱이 비대해지다보니 메모리 관리에 어려움이 있습니다ㅠ_ㅠ

1개의 좋아요

android에서 ItemTemplate 내의 switch는 터치 자체가 동작안하던데 혹시 이 문제는 해결해보진 않으셨어요?