라벨이 [Angular]인 게시물 표시

[Angular] 모델, 값이 바뀌었는데 화면 template 이 업데이트 되지 않을 때 조치 팁

안녕하세요. 명동섞어찌개입니다.

Angular 로 화면을 만들다 보면 종종 서버에서 값을 읽어와서 비동기로 화면이 업데이트 되는 상황에서, 화면에 바뀐 값이 반영되지 않는 경우가 생깁니다.

분명 ts (typescript) 의 값은 바뀌었고, 서버에도 문제가 없는데 html template 화면만 값이 제대로 표시되지 않는 경우가 있습니다.

이럴 때 사용할 수 있는 간단한 방법을 공유하려고 합니다.


1. ngIf = "flag == true" 를 씁니다. data.html

1 2 3 4 5<div*ngIf="data.length > 1"><span*ngFor="let item of data; let idx=index"><span>{{item}}</span></span></div>

data.ts

1 2 3 4 5 6 7 8 9 10 11 12 13 14data=null;...getData(){this.dataService.getDatas().subscribe(data=>{this.data=data.result;},({error})=>{})}
비동기로 서버에서 값을 읽어올 때, 값이 들어온 시점에 (data.length > 1) 정확히 데이터를 들고 화면을 그려주기 위해 template 쪽에 ngIf 문을 이용해서 그려줍니다.

저런식으로 화면 일부가 데이터가 계속 바뀜에 따라 지속적으로 업데이트 되어야 하는데, 값은 잘 들어오지만 template 은 새로 그려지지 않을때 flag 를 하나 세팅해서 ngIf 로 제어하면 화면이 잘 바뀝니다.


예를 들어

[A 컴포넌트]  ---(click)--->  [B 컴포넌트]

A 컴포넌트에서 메인 메뉴를 클릭할 때 B 컴포넌트에서 각 서브메뉴 값들을 서버에서 새로 불러오는 상황에서
ts 는 값이 문제 없이 찍히는데 화면 템플릿은 업데이트 되지 않을 때

<compone…

[Angular] history back 기능 구현 : 상세 화면 뒤로가기하여 목록 화면으로 이동 시 검색조건 그대로 보여주기

이미지
안녕하세요, 명동섞어찌개입니다.

오늘은 관리자 화면에서 검색 조건을 선택해서 검색 후, 필터링 된 결과물 상세보기를 한 다음 뒤로 돌아갔을 때 기존 검색조건이 그대로 남아있도록 하는 방법에 대해 알아보겠습니다.

말로 하니까 어려운데요;; 아래 화면을 보시면 !!



저 빨간 박스 부분에서 검색 조건을 선택하고, 아래에 필터링 된 결과물 목록 중 하나를 클릭해서 상세 페이지로 갔다가, 다시 목록 페이지로 돌아오면 기존에 선택한 검색 결과가 저장되지 않고 사라지는데요. 그걸 보존하는(?!) 방법을 알아보겠습니다.

구현 방법은.. 저같은 초짜는 localStorage 를 쓸까 cookie 를 쓸까 (.....;;;;) 별 생각을 다 하지만 가장 간단하고 흔하고 안전한 방법은 route 를 이용하는 겁니다

주소창에 뒤에 조건식을 ? 다음에 & 로 구분해서 보존하는 거요. 아래처럼요.

https://devcloud.ipatioplatform.com/admin/cdn/list?inputKey=originalFileName&inputValue=&deletedYn=N&organizationId=1234995959595&taskSystemId=&templateId=&from=2015-04-06&to=2020-04-06&periodKey=created&sortBy=



1. 먼저 저희 쪽 목록 화면이 어떻게 구현되어있는지 간단하게 살펴보겠습니다. cdn-list.component.html

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20<mat-form-fieldclass="customSelector"><mat-label>이용기관</mat-label><mat-select[(value)]="searchParams.organizationId"(selectionChange)="on…

[Angular] HTTPInterceptor 를 이용하여 파일 업로드 중지하기

안녕하세요. 명동섞어찌개입니다.
오늘은 Angular 에서 파일 업로드 기능 개발 시, 원하는 시점에 파일 업로드를 중지하는 기능에 대해 알아보도록 하겠습니다.

요점은 페이지 이동이나 파일 업로드 취소 버튼을 누르는 순간, HTTPIntercepter 를 이용하여 서버에 보내는 요청을 취소하여 파일 업로드를 중지하는 기능을 만드는 겁니다!


1. HttpCancelService 를 만듭니다실질적으로 http 요청을 취소하는 부분입니다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19import{Injectable}from'@angular/core';import{Subject}from'rxjs';@Injectable()exportclassHttpCancelService{privatependingHTTPRequests=newSubject<void>();constructor(){}publiccancelPendingRequests(){this.pendingHTTPRequests.next();}publiconCancelPendingRequests(){returnthis.pendingHTTPRequests.asObservable();}}


2. 공통으로 어느 페이지에서나 호출하기 위해서 이벤트를 설정해 줍니다. 이거는 만드는 방식의 차이인데요
저는 어느 페이지에서나 접근 가능한 공통 commonCode 에 페이지 공통으로 쓸 이벤트를 하나 정의해 두었습니다. (이벤트를 쓰는 건 간편하긴 하지만 남발할 경우 ...... 권장하지는 않습니다. 프로젝트 상황에 맞게 쓰세요!)

1exportconstCOMMON_EVENT=newEventEmitter();


3. HTTPIntercepter 를 만듭니다 위에서 만든 공통 이벤트를 통해 'stop_file_upload' 라는 요청을 보내면 이 Interceptor 가 듣고, httpCancelService 의 함수를 호출해서 htt…

[Angular] 저장되지 않은 파일이 있는데 뒤로 가기를 누른 경우 경고 알럿 띄우기

이미지
안녕하세요. 명동섞어찌개 입니다.

오늘은 Angular 페이지에서 문서 (form) 작성 중 또는 무언가를 등록하다가, 저장하지 않고 브라우저 뒤로가기 버튼을 눌렀을 때 '저장하지 않은 파일이 있습니다. 페이지를 나가시겠습니까?'라고 묻는 알럿 띄우는 기능을 만들려고 합니다.



일반적으로 이런 기능은 javascript 에서는 popstate 이벤트 리스너를 사용해서 구현합니다. (모바일에서도 사용한 기억이 있습니다.)

1 2 3window.addEventListener('popstate',(event)=>{console.log("location: "+document.location+", state: "+JSON.stringify(event.state));});
하지만 Angular 에서 window:popstate 로 아무리 구현해 봐도 원하는 기능이 작동하지를 않더군요.

아마도 popstate 는 페이지가 이동할 때 호출되는 이벤트인데, Angular 는 SPA(Single Page Application) 다 보니 하나의 페이지 안에서 component 끼리 routing 될 뿐이라서 저 이벤트가 호출되지 않는 듯 했습니다. (자세히 아시는 분은 댓글로 제보 부탁드립니다!!)

검색해보니 Angular 자체적으로 페이지를 나갈 때 처리해줄 수 있는 솔루션이 있더라구요.
router 의 canDeactivate !!!

canActivate 는 로그인하지 않은 사용자가 해당 페이지에 접근하지 못하게 막는 용도로 사용되는 경우를 많이 봤는데요, 페이지를 나갈 때 체크하는 용도로 canDeactivate 를 사용해 본 건 처음이었습니다.


시나리오를 말씀드리자면

1. CdnRegisterComponent 라는 페이지 컴포넌트에서 파일을 등록하다가 저장 버튼을 안 누르고
2. 브라우저 뒤로가기 버튼을 눌렀다!

이 경우에 알럿이 뜨게 하는 처리입니다.


1. CdnRegisterComponent 페이지에 저…

[Angular] File Upload > Drag and Drop 만들기

이미지
안녕하세요. 명동섞어찌개입니다.
오늘은 Angular 를 이용한 파일 업로드 기능 개발 시 편리한 사용성을 위해 Drag and Drop 드래그 앤 드랍 기능을 추가하는 방법을 알아볼건데요,

vanila javascript(순수 자바스크립트) 로 개발하면 익스플로러와 크롬 브라우저 등 브라우저 별 예외처리가 필요해서 시간이 꽤 걸리는 일이지만(개인적으로 0 부터 시작해서 개발했을 때 다른 업무 처리하면서 일주일 정도 걸렸습니다..)Angular 는 directive 를 사용해서 간편하게 개발할 수 있더라구요.

Angular Version: 8

결과화면 1. 먼저 drag-and-drop directive 를 만듭니다.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52import {Directive, EventEmitter, Host, HostBinding, HostListener, Input, Output} from '@angular/core';@Directive({selector: '[appDragDrop]'}) export classDragDropDirective{@Output() onFileDropped =new EventEmitter<any>();@Input('draggable')public draggable =true;@HostBinding('hintLine')public deco =false;@HostBinding('style.background-color')public background = '#fff';@HostBinding('style.opacity')public opacity ='1';//Drago…

[Angular] HttpInterceptor를 사용하여 Token 만료 검증하기

안녕하세요. 남산돈가스입니다.
이번 포스팅에서는 Angular 프로젝트 환경에서 API를 요청하실 경우, 가장 보편적으로 사용하시는 HttpClientModule에서 Http 요청을 가로채 특정 처리를 할 수 있도록 도와주는 HttpInterceptor 인터페이스에 대해서 작성해보겠습니다.

우선 HttpInterceptor는 Angular 4.3부터 추가 된 기능으로,
위에서 말한 것처럼, HttpClientModule을 이용한 API 호출 시 그 중간의 요청을 가로채어 특정 처리를 진행할 경우에 사용합니다.

저희 팀에서 Angular를 진행하는 프로젝트에서는 이 Interceptor를 API 호출 시 OAuth Token을 만료인지 유효한 지 검증하기 위한 용도로 사용되고 있습니다.

이번 포스팅에서 예제로 설명할 상황은 이렇습니다.

1. LocalStorage에 저장 된 OAuth Token을 가져온다.

2. OAuth Token을 요구하는 API를 HttpClient 모듈을 이용하여 호출한다.

3. HttpInterceptor에서 API  결과 응답이 Error이며, 401에러인 경우를 확인한다.

4. 상황이 3 과 같은 경우, 토큰 갱신 API를 호출한다.

5. 토큰 갱신 이후 정상 토큰을 가지고 위에서 호출해야하는 API 다시 요청한다.

6. 정상 응답을 확인한다.

예제 코드를 보면서 설명하겠습니다.


import {Injectable} from '@angular/core'; import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; import {Observable} from 'rxjs'; @Injectable() exportclass TokenCheckInterceptor implements HttpInterceptor { intercept(req: HttpRequ…

Angular2+ 에서 넘치는 글자 말줄임표(...) 처리하기

Angular2+ 에서 말줄임(...) 처리는 크게 세 가지로 할 수 있습니다.

1. Pipe 로 템플릿 단에서 처리

2. 스크립트 처리

3. CSS 로 처리
1줄일 경우, 2줄 이상일 경우 다른 방법이 쓰입니다.

이 세 가지에 대해 간단한 핵심 소스를 공유 드립니다.


1. Pipe

*.ts
str:string = '일이삼사오육칠팔구십'

*.html
<div> {{ (str.length>6)? (str | slice:0:6)+'...':(str) }} </div>

결과화면
일이삼사오육...



2. 스크립트 사용

*.ts
var limitLen = 6;

if (str.length > length) {
     str = str.substr(0, limitLen) + '...';
}

*.html
<div> {{ str }} </div>

결과화면
일이삼사오육...



*jquery ellipsis 사용

See the Pen jQuery ellipsis by jaeheekim (@jaehee) on CodePen.


2. CSS 사용

1줄일 경우

div {
   white-space:nowarp; /* 줄바꿈 막음*/
   text-overflow:ellipsis; /* ... 로 보이게 */
   overflow:hidden;
}


2줄 이상일 경우

div {
     font-size:1em;
     overflow:hidden;
     text-overflow:ellipsis;
     line-height:1.5;
     height:3em;  /* line-height의 두 배 */
     display:-webkit-box;
     -webkit-line-clamp:2; /* 나타낼 글자 라인 수 */
     -webkit-box-orient:vertical
}



2줄인데 영문 + 한글이 섞여 있어서 높이값을 정해주면 아래쪽이 잘려보이는 등 약간 까다로운 경우

가 이번에 생겨서 다른 쇼핑…