2019. 3. 11. 15:15ㆍProgramming/AngularJS
임베디드 장비에 서버를 올려서, 장비의 설정을 변경할 수 있는 웹 어플리케이션을 서비스하고 있다. 그건 그렇다치고 몇 년 전부터 골치아픈 문제가 있었는데,
ng-include
를 사용해서 페이지를 로드했을 때 연결된Controller
가 두 번 호출되고 있었다.
Controller
가 두 번씩 호출되는 문제는 생각보다 골치아픈 문제였다. 장비에서 받아오는 데이터가 많으면 많을수록 Controller
에서 데이터를 가공하는 코드도 복잡해지기 마련이었는데, Controller
가 두 번 로드되면서 초기화하는 코드가 두 번 동작하는 것도 환장할 노릇이었다. 단순히 사용자에게 현재 장비의 설정값을 보여주고, 변경할 수 있게끔 하는 페이지라면 문제는 없었다. 하지만 특정 UI가 다른 UI의 값들과 의존관계가 있다거나, 각각 설정값의 범위나 의존관계가 다른 장비들을 여러대 연동한다면 상당히 골치아픈 문제가 됐다. 안그래도 초기화에 n^2의 시간이 걸리는데, 이 코드가 두 번씩 동작해서 버벅거리기까지 한다.
ng-include page twice
나ng-include controller twice
등으로 검색해보면 상당히 다양한 검색결과를 발견할 수 있다. ng-include same partial page twice in a page, stackOverflow와 같은 내용들이다. 문제는 내가 직면한 문제와는 전혀 다른 문제였다. 1년 전에는 동일한 문제를 좇다가 일정에 가로막혀서 결국 포기했었는데, 이번에는 원인을 파악할 수 있었다.
힌트는 처음 페이지를 로드할때 발생하지 않고, 다른 메뉴를 클릭했을 때 발생한다는 점이었다. AngularJS: when $location changes path and actual path has Query String, it causes that new path is loaded twice times, Radek Anuszewski 페이지와 Common Angular Routing Challenges, Rapid7 Blog를 보다가, $location.path
를 $location.search
로 변경해봤다. 주소표시창의 주소는 변경되지 않았지만, Controller
는 한번만 호출되고 있었다. 잠깐, 근데 $location.search
가 페이지를 이동해주는 녀석이었나?
$location.search
는 현재 url의search part
에 대한 getter/setter이다. 즉, 페이지를 로드하는데는 전혀 상관이 없는 녀석이다. 그런데 어째서$location.search
를 호출했는데 페이지가 전환될 수 있었을까?
답은 생각보다 간단했다.
//ng-include로 페이지를 로드하는 html파일 내부
<div ng-include src="'views/' + currentPageId + '.html'"></div>
//메뉴를 클릭했을 때 페이지를 전환해주는 Javascript 내부
$scope.currentPageId = id;
...
$location.path(id);
html
파일에 바인딩 된 ng-include
의 src
값을 보면, $scope.currentPageId
라는 값을 참조하고 있었다. 그리고 controller
내부에 메뉴 클릭시 동작하는 핸들러의, $location.path
호출위치 앞에, $scope.currentPageId
값을 변경하는 코드가 있었다. $scope.currentPageId
가 변경되면서 페이지가 한 번 로드되고, $location.path
가 호출될 때 페이지가 다시 한 번 로드되고 있었다. 코드를 작성할 때 발생한 문제였지만, 코드 분석보다 검색 결과에 의지했기 때문에 원인을 발견하기 힘든 문제였다 = ㅅ=
…
앞으로 검색도 검색이지만, 코드를 먼저 꼼꼼히 분석부터 해야 할 듯 싶었다. 에휴.
'Programming > AngularJS' 카테고리의 다른 글
[BootStrap] 탭 내용 전환하기 전에 다이얼로그를 띄우기 (0) | 2019.03.19 |
---|---|
[angularJS] ng-change/ng-click 내에서 ng-model로 바인딩 된 값을 변경할 시, UI에 변경된 값이 표시되지 않는 경우 (0) | 2019.03.12 |
Unsupported Selector Lookup. Looking up elements via selectors is not supported by jqLite (0) | 2016.10.19 |
IE10에서 Select를 그리지 못하는 버그 (0) | 2016.02.20 |
AngularJS 2.0에서 달라진 점 정리 (0) | 2016.02.10 |