2019. 5. 7. 19:59ㆍProgramming/AngularJS
2019/03/12 - [Programming/AngularJS] - [angularJS] ng-change/ng-click 내에서 ng-model로 바인딩 된 값을 변경할 시, UI에 변경된 값이 표시되지 않는 경우
이 글과 비슷한 내용이다. ng-change/ng-click 내에서 ng-model로 바인딩 된 값을 변경할 때의 문제이다.
ng-options
를 활용하여 select
를 작성하는 경우, ng-options
내에 선언한 배열이나 객체를 변경하면 값이 초기화된다. 이전에 언급했던 글과 비슷한 현상인데, 렌더링을 다시 하기 때문에 ng-options
내의 가장 처음 값이 선택되어버리는 문제이다. 하지만 ng-model
값은 변경되지 않으므로, ng-change
가 발생하지도 않는다. UI를 클릭해서 이전 값으로 변경했을 때도 실제 ng-model
로 바인딩되어있는 값은 변경되지 않기 때문에, ng-change
가 발생하지 않는다.
가장 중요한 대목은 UI상에서는 ng-options
의 가장 처음 값이 선택된 것처럼 보이지만,실제 ng-model
으로 바인딩되어있는 값은 변경되지 않기 때문에 렌더링이 되지 않는다. 실제로 이 문제를 처음 맞딱드리게되면 상당히 짜증나게된다. 이런 경우에는 Select에 DOM id
를 설정해주고, 바닐라 자바스크립트로 변경해주는 수밖에 없다.
<select ng-options="option.value as option.label for option in options | filter:cantSelectableOption" ng-model="current_option" ng-change="optionChangeHandler($index)" id="select"/>
이제 id값을 이용해서 select에 접근할 수 있다.
위처럼 id값을 작성하게되면 document.getElementById
를 이용해서 돔을 불러올 수 있다. 다만 문제가 있다. angularJS에서 렌더링한 값은 실제 값과는 달리 index 순서이며, label의 값이 각 옵션의 text에 할당되게 된다. 따라서 실제 options
의 값이 변경되었을 때 DOM을 조작하기 위해서는, 다음과 같은 절차를 거쳐야 한다.
var index_of_option = 0; var text_of_option = ""; for(var i=0; i<$scope.options.length; i++) { if($scope.options[i].label == document.getElementById("select").text) { index_of_option = i; } } document.getElementById("select").value = index_of_option;
위와같은 방식으로 DOM객체를 직접 컨트롤해서 대처할 수 있다.
추가적으로 select 자체를 ng-repeat
내에서 사용하는 경우, $index
를 사용하여 각 select의 id를 다르게 선언할 수 있다.
<div ng-repeat='select_model in selects'> <select ng-options="option.value as option.label for option in options | filter:cantSelectableOption" ng-model="current_option" ng-change="optionChangeHandler($index)" id="select_{{$index}}"/> </div>
위와 같은 방법으로 선언하면 select_0, select_1, select_2, ..., select_N과 같은 형태로 id가 할당된다.
사실 요약하면 'ng-options로 바인딩 한 배열/객체의 값을 변경한 경우, 바닐라 자바스크립트를 이용해서 DOM을 컨트롤하세요'라는 한 줄로 요약할 수 있는 글이다. 일반적으로 ng-options로 바인딩해놓은 배열을 변경할 일은 거의 없기 때문에, 마주칠 일은 없을 듯 하다. = ㅅ=)
'Programming > AngularJS' 카테고리의 다른 글
[AngularJS 1.x] EventQueue에서 Controller의 $scope를 사용하면 발생하는 문제 정리 (0) | 2019.05.16 |
---|---|
[BootStrap] 탭 내용 전환하기 전에 다이얼로그를 띄우기 (0) | 2019.03.19 |
[angularJS] ng-change/ng-click 내에서 ng-model로 바인딩 된 값을 변경할 시, UI에 변경된 값이 표시되지 않는 경우 (0) | 2019.03.12 |
ng-include로 불러온 페이지의 Controller가 두 번 호출되는 문제 (0) | 2019.03.11 |
Unsupported Selector Lookup. Looking up elements via selectors is not supported by jqLite (0) | 2016.10.19 |