배경설명 (프로세스 흐름)
- input checkbox 클릭
stplList: [
{
title: '첫번째 checkbox',
checked: false,
},
{
title: '두번째 checkbox',
checked: false,
},
...
],
deepCopyObj: {},
shallowCopyObj: {},
// html sample
<div v-for="item in stplList" @click="handleStplClick(item)">
<input type="checkbox" v-model="item.checked">
<label>{{ item.title }}</label>
</div>
- checked (참조 타입 하위에 선언) 여부에 따라 분기
- (이슈 발생 case) checked false case : popup show
- 동의 클릭 : checked true
- 닫기 클릭 : checked false
- checked true case : checked false 설정
handleStplClick: function(stplObj) {
const bfchgChecked = stplObj.checked;
if (bfchgChecked === false) {
CmnUtil.deepCopy(this.deepCopyObj, stplObj);
this.shallowCopyObj = stplObj;
this.showStplPopup(stplObj);
} else if (bfchgChecked === true) {
stplObj.checked = false;
}
},
이슈
- (3. 번 case) input checkbox click 직후 checked true 설정되며 제어 불가
해결방안
- (제외) readonly 속성 활용하여 checked 설정 안 되도록 적용
- readonly 속성 적용 시, disabled과 동일한 css 적용 (퍼블 표준)
- (채택) 참조 타입 복사를 통해 input checkbox의 checked 상태를 click 직전/직후 상태를 따로 관리
- 직전 : 깊은 복사 -> checked false
- checked true 설정되기 전에 완전한 복제본 생성
- 직후 : 얕은 복사 -> checked true
- checked true 설정된 후에도 원본의 메모리 주소값을 그대로 참조
얕은 복사 (deep copy) vs 깊은 복사 (shallow copy) 비교
- 참조 타입 copy 시 값이 저장된 메모리 주소가 복사되어 저장된다.
- 비교
구분 | 설명 | 메모리 주소값 동일 여부 |
---|
얕은 복사 | 메모리 주소값 복사 | O |
깊은 복사 | 새로운 메모리 주소 공간에 완전한 복제본 생성 | X |
조치 소스 샘플
callbackStplPopupClose: function(agreeYn) {
if (agreeYn === 'N') {
this.shallowCopyObj = false;
} else if (agreeYn === 'Y') {
this.callbackStplChecked(this.deepCopyObj, this.stplList);
}
this.shallowCopyObj = {};
this.deepCopyObj = {};
}
교훈
- 얕은 복사와 깊은 복사를 잘 활용하면 복잡한 비지니스 로직을 구현하는데 큰 도움이 된다!
참고