Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

angular-summernote v0.2.4 릴리즈

지난번 릴리즈 후 한 달 정도 만에 새버전을 릴리즈했다. 여름 이후부터는 사용자들이 좀 있는지 저번에 이슈를 다 털었는데도 그 사이에 이슈가 몇 개 올라왔다. 그래서 이번 릴리즈는 마이너 버그 수정 버전이다. 버그 하나 수정하고 릴리즈하는 게 좀 애매하기는 했지만, 오류가 발생하는 거라서 수정을 했다.

이슈ng-repeat사이에서 동적으로 summernote를 생성하고 제거하는데 제거할 때 오류가 발생한다는 내용이었다. 이슈가 잘 이해 안 돼서 코드를 받아서 테스트해보았더니 실제로 발생했다. 추적을 해보니 Angular.js의 스코프가 제거될 때 summernote를 제거하기 위해서 destroy()함수를 실행하는데 여기서 summernote DOM에 바인딩해 놓은 옵션객체를 data()로 받아와서 확인하는데 data()가 빈 객체로 나왔다.

$scope.$on('$destroy')로 이벤트를 받아서 summernote를 제거하는데 테스트해보니 data() 객체가 계속 정상적으로 있다가 이 이벤트로 받아서 넘어오면 빈 객체로 바뀌어 버린다. angular.js 소스를 추적해 봐도 정확한 원인까지는 찾지 못했는데 삭제 전에 DOM 객체를 제거하고(혹은 어떤 정리작업) 넘겨주는데 이때 data()로 바인딩한 값이 없어지는 것 같다.(이게 버그인지 의도인지는 잘 모르겠다.)

$destroy 이벤트의 문서를 보면 다음과 같이 나와 있다.

Note that, in AngularJS, there is also a $destroy jQuery event, which can be used to clean up DOM bindings before an element is removed from the DOM.

$destroy는 스코프 내에서 이벤트를 브로드캐스팅하지만 동시에 $destroy jQuery 이벤트도 발생시키므로 둘 다 사용할 수 있다. 정확히는 $destroy 이벤트가 먼저 발생하고 이후에 Angular.js의 $destroy 이벤트가 브로드캐스팅된다. 그래서 $(element).on('$destroy')로 이벤트를 받으니까 data()에 옵션객체가 제대로 존재에서 오류 없이 ng-repeat내에서 오류 없이 제거할 수 있었다.

다만 기존에 summernote 삭제 테스트를 작성해 놓은 부분이 있어서 $scope.destroy();로 직접 제거하는 테스트코드가 있었는데 이때는 jQuery 이벤트가 발생하지 않아서 summernote가 제거되지 않았다. 결국은 별수 없이 jQuery $destroy이벤트 내에서 삭제를 나타내는 플래그를 하나 추가하고 Angular.js의 $destroy이벤트에서 이 플래그가 없을 때만 제거하도록 했다.(꼼수 같은 기분이 들어서 angular.js를 더 공부해야겠다. ㅠㅠ)

Angular.js가 1.3.0이 RC에 진입해서 다음 수정은 1.3.0 호환성 작업이 될 것 같다. Angular 버전도 이제 여러 버전에서 테스트해 돌려야 하는데 어떻게 환경 설정하는지도 찾아봐야 할 듯...(Travis ci에서는 건드리지도 않은 테스트가 왜 깨져 ㅠㅠ )

2014/10/04 23:32 2014/10/04 23:32