씨에수에수왕

2024년 3월 26일 화요일

Today I Learned

날짜

2024년 3월 26일 화요일

내용

다 고쳤다고 생각했는데, 이젠 위젯 수정 과정에서 발생한 오류들이…

위젯 수정 후 렌더링

썸네일

렌더링과는 별개로, 처음 위젯을 생성할 때는 상품의 썸네일 이미지도 가져와서 설정하는 로직이 있다. 그런데, 이미 존재하는 위젯을 수정하는 과정에서 상품을 추가할 때는 썸네일을 가져오지 않았다. 추가해주었다.

레이아웃 수정

행,열의 값이나 레이아웃 형태를 변경하면 위젯이 고장나버리는 문제가 있었다. 디자인 옵션은 받은 값을 통채로 덮어씌워져서 개별 값이 문제가 될 리가 없었다. 로그를 확인해보니 currency가 문제가 있었다. 뜬금없이 애는 또 왜….

알고보니 위에서 발생한 문제와 동일했다. 상술하였듯, 위젯을 수정할 때 받은 데이터를 그대로 덮어씌워 데이터 레코드에 반영한다. 이때, currency는 None 값이 되버린다. 클라이언트에게 받은 데이터는 currency 필드가 없기 떄문이다! 결국 별도로 지정해주는 로직을 추가해서 해결했다.. 지긋지긋한 currency

프론트 코드리뷰

작게 맡게 된 프론트 태스크에 대한 코드리뷰를 받아서 수정했다.

중복 코드 방지

한 서비스 내에서 사용되는 요소들(버튼, 체크박스, 셀렉트박스)등은 보통 같은 CSS가 적용된다. 확인버튼이 이 페이지와 저 페이지가 전혀 다른 크기와 모양을 가지면 정신 사나우니까.. 그래서 우리 서비스에서 사용되는 것들에 대한 참조 클래스가 대부분 만들어져있다. 만약 별도로 CSS 적용이 필요하다고 하더라도, 이미 다른 곳에서 쓰이고 있는 경우가 많다. 애초에 새로 만들어야 하는 어려운 게 지금의 내 수준에선 맡을 일 없는 태스크니까..

어드민에서 사용되는 요소들은 admin 컴포넌트에서 최상위에 less 파일내에 있었다. 색깔들도 헥스 코드가 아니라 별도로 지정된 클래스가 있었다. 버튼, 섹션, 입력칸 등 대부분의 요소들은 기존 클래스를 가져와서 해결했다. 애초에 기획과 디자인에서도 이미 사용한 적이 있는 형태를 쓰니 당연한 듯.

클래스에 별도의 CSS가 필요할 경우에는, 다른 페이지를 싹 다 뒤지면 해결됐다. 분명 우리 서비스 내 어딘가에 똑같은 색깔, 모양, 크기를 가진 요소가 존재했었다. 그 코드를 복붙하면 해결됐다.

Flex

CSS를 하다보면 display: flex를 쓰는 경우가 많았는데, 뭔지도 모르고 썼다. 근데 CSS의 공식 문서는 어디지..? 그냥 위키백과를 찾아봤다. (링크)

One of the most defining features of the flex layout is its ability to form-fit, based on its viewing environment. Flex boxes can adjust in size—either decreasing, to avoid unnecessarily monopolizing space, or increasing to make room for contents to fit within its boundaries.

어떤 폼을 형성하여 사이즈를 조절하도록 해준다고 한다. 감이 살짝 안와 다른 곳을 참조했다.

출처 : w3school

Before the Flexbox Layout module, there were four layout modes:

  • Block, for sections in a webpage
  • Inline, for text
  • Table, for two-dimensional table data
  • Positioned, for explicit position of an element

The Flexible Box Layout Module, makes it easier to design flexible responsive layout structure without using float or positioning.

Flex가 아니라면, 웹 페이지에서 CSS를 다룰 때 묶을 레이아웃 단위는 4가지라고 한다.

  1. 블록 : 한 페이지 내의 섹션
  2. 인라인: 텍스트 단위 한 줄
  3. 테이블 : 2차원 데이터
  4. 포지션: 외부에서 보이는 요소의 위치

Flexbox, Flex container는 이 4개가 아닌, 하나의 박스라고 생각하면 될듯 하다. 한 뭉태기 정도..? 따라서 display: flex는 레이아웃을 flexbox 단위로 보겠다는 선언이다. 실제로 display에 커서를 올려놓면 뜨는 설명도

In combination with ‘float’ and ‘position’, determines the type of box or boxes that are generated for an element.

이다. 요소로 생성되는 박스들의 타입을 결정하는 방식이라고 한다.

이 플렉스 뭉태기는 방향을 설정할 수 있다. 우리야 당연히 “위에서 아래겠지”라고 생각하지만, 그렇지 않을 수도 있다. 따라서 flex-direction: column을 설정해줘야 한다. 안하면 인셉션마냥 모든 요소가 드러눕는다. flex-direction에 뜨는 설명은 다음과 같다.

Specifies how flex items are placed in the flex container, by setting the direction of the flex container’s main axis.

컨테이너(박스)들이 놓이는 방향의 중심선을 설정하는 것.

gap

flex를 알아보게 된 이유는, gap이 적용이 안됐기 떄문이다. 각 요소들 간의 간격을 설정해야 하는데 안되고 있었다. 나는 gap을 하면 div끼리 벌어지는 줄 알았는데… 미리 flex를 설정해서 “그래서 어떤 것들의 간격을 벌릴건데?”에 대한 대답이 선행되야 한다. 결론은 display 설정 안하면 gap은 안먹는다.

반복문

다양한 선택지를 표시하기 위해 HTML에서 반복문을 사용한다. 여러 체크박스들을 만들고 체크 여부를 데이터에 바인딩하기 위해 ngFor을 사용했었다. 사실 ngFor도 제대로 쓸 줄 모르지만 다들 쓰길래 따라서 복붙하고 있었다.

Angular17 부터는 @for를 사용할 수 있는데, 성능이 올라간다고 해서 썼다.

1
2
3
4
5
6
7
<div class="checkbox-container">
      @for (reason of uninstallReasonDict; track $index) {
        <alpha-checkbox (click)="updateUninstallReasons(reason.value)">
        
        </alpha-checkbox>
      }
</div>

uninstallReasonDict 에는 key와 value 형태로 출력될 사유와 값을 가지고 있다. 예를 들어,

{ ‘key’: ‘Too much premium plan’, ‘value’ : 10} 과 같은 형식으로. 메시지는 화면에 출력하고, 선택된 이유들을 담을때는 숫자로 담았다. 클릭할 때 실행되는 함수는 value가 배열에 없다면 추가하고, 있으면 삭제하는 함수였다.

유동적 클래스

ngClass를 사용하면 요소에 유동적으로 클래스를 부여할 수 있었다. 예를 들어, 방금 체크박스는 selectedReasons 라는 배열에 값을 저장한다. 이 배열에 값이 존재할 떄만 버튼을 활성화 하도록 구현해야 했다. 쉽게 말해, 선택해야만 누를 수 있는 버튼을 만들어야 했다.

1
2
3
4
5
<button 
	class="btn-confirm" (click)="onConfirm()" 
	[ngClass]="{ disabled: selectedReasons.length === 0}">
		Delete App
</button>

활성화 됐을 때의 색깔이나 CSS는 btn-confirm 에 적용하면 되고 비활성화 관련 CSS는 disabled에 적용하면 된다. selectedReasons 배열이 비어있다면 이 버튼의 클래스에는 disabled가 추가된다. 값이 들어와서 배열의 길이가 0이 아니게되면 disabled 클래스는 다시 제외된다.

CSS는 다음과 같이 적용하면 된다.

.btn-confirm {
      background-color: #8e1f0b;
      cursor: pointer;

      &.disabled {
        pointer-events: none;
        background-color: @disabled-gray;
        color: @border-focus-gray;
      }
    }

깔끔하다.

회고

빨리 배워서 2인분을 할테다.