NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    Web Angular에서 값이 변경되면 다른 컴포넌트에서 변경된 값을 받아서 처리하는 방법.

    페이지 정보

    본문

    앵귤러 이벤트를 구독하는 옵저버블(Observable)은 앵귤러 기능은 아닙니다. ES7에서 비동기 데이타를 관리하기 위한 새로운 표준으로 추가되었습니다. 처음 앵귤러를 접하게되면 여러가지 새로운 개념들을 배워야 하는데요. 대부분은 개발자적인 센스(?)를 갖추고 있다면 쉽게 이해할 수 있을겁니다. 하지만, Observable과 Subscription을 이해하는데 약간의 노력이 필요합니다. 간단한 예로 아래와 같이 Draw Option 콤보 박스의 내용을 변경하면 다른 컴포넌트가 변경 내용을 구독하고 있다가 Alert을 띄워줍니다.

    F21LERE.png

     

     

    화면은 각각 Condtion, Chart, Grid와 같은 컴포넌트로 구성되어 있습니다. Draw Option은 Condition 컴포넌트에 포함되어 있습니다. Draw Option에 따라 Chart가 그려지는 방식이 달라집니다. 그렇기 때문에 Condition 컴포넌트에서 Draw Option이 변경될 때 구독자들에게 값을 전달할 옵저버블을 만들어줍니다. 그러나~ Angular 프로젝트를 진행하는 곳은 대부분 비동기로 서버와 통신하면서 데이타를 받아오고 있을겁니다. 그래서 Service를 만들어서 중앙에서 관리합니다. 위 화면에서도 GAP 앞쪽에 많은 모듈들이 있는데요. 대부분 Condition은 동일하기 때문에 코드 재사용을 위해 이런식으로 구성하고 있습니다. 물론, 지금 이 예제는 컴포넌트간 데이타 전달이기 때문에 간단합니다.

    <!-- Condition Component Html -->
    <div id="GapConditionContainer" style="width: 100%; height: 60%;">
    	<h4>Draw Option</h4>
    	<nz-select
    		#ngDrawOption
    		style="width: 100%;"
    		nzPlaceHolder="Please select"
    		(ngModelChange)="provinceChange('', $event)"
    		[ngModel]="drawOptionData"
    	>
    		<nz-option nzValue="1" nzLabel="1"> </nz-option>
    		<nz-option nzValue="2" nzLabel="2"> </nz-option>
    		<nz-option nzValue="3" nzLabel="3"> </nz-option>
    		<nz-option nzValue="4" nzLabel="4"> </nz-option>
    	</nz-select>
    </div>

     

    Select 박스에서 ngModelChange 이벤트에 provinceChange를 할당 했습니다. Typescript에서 이벤트를 구현 해줍니다.

    // Condition Component Typescript
    import { NgmService } from './services/ngm.service';
    
    constructor(
    		private pluginService: PluginService,
    		private cdr: ChangeDetectorRef,
    		private ngmService: NgmService,
    		...
    	) {}
    
    provinceChange(currentAttributeName: string, values: string) {
    	GapConditionInfoComponent.cdnDrawOption = values;
    	this.ngmService.gapDrawOptionSubject.next(values);
    }

     

    서비스는 크게 3가지를 처리해줍니다. 서로 다른 컴포넌트 간 데이타를 주고 받거나 HTTP 모듈이 Ajax 요청을 보내거나 응답을 받아서 처리합니다. 이 때에는 요청을 받아서 응답을 처리해줄 서버가 필요합니다. 그리고, 라우터와 폼 모듈이 사용자 입력 이벤트를 감지할 때도 옵저버블을 사용합니다. 아무튼~ 아래에서는 컴포넌트 간 데이타 전달을 사용하고 있습니다.

    gapDrawOptionSubject: Subject<any> = new Subject();
    
    // 컴포넌트 간 데이타 전달
    getGapDrawOptionObservable(): Observable<any> {
    	return this.gapDrawOptionSubject.asObservable();
    }
    
    // HTTP Ajax 요청 처리
    getNextAttributeValues(dataSetConfigRequest: DataSetConfigRequest): Observable<any[]> {
    	const api = 'nextattributevalues';
    	const options = {
    		notUsePrefix: true,
    		retryCount: 0,
    		params: dataSetConfigRequest,
    	};
    	return this.httpService.post(api, options);
    }
    
    // HTTP Ajax 응답 처리
    ...
    ...

     

    Condition Component에서 Draw Option이 변경되면 다음 코드가 실행됩니다. "this.ngmService.gapDrawOptionSubject.next(values);" 여기서 next로 옵저버블을 구독하는 모든 컴포넌트에 Push플 보낼 수 있습니다. 그러면, 아래 코드에서와 같이 Chart Component는 ngOnInit에서 subscribe로 값이 들어오게 됩니다.

    // Chart Component Typescript
    import { NgmService } from './services/ngm.service';
    
    constructor(
    	private ngmService: NgmService,
    	private cdr: ChangeDetectorRef,
    	private plotlyZoomService: PlotlyZoomService,
    	private plotlyLayoutChartService: PlotlyLayoutChartService,
    	...
    	...
    ) {}
    
    ngOnInit(): void {
    	this.ngmService.getGapDrawOptionObservable().subscribe((drawOption) => {
    		this.drawOption = drawOption;
    		alert(drawOption);
    	});
    }

    s1Jsq79.gif

     

    그냥 예제 코드로 작성하면 별거 아닌데... 실제 프로젝트에서 사용하려다보니 설명이 좀 복잡해진듯 합니다. 사실, Service에 정의 해둔 Subject와 Observable은 Condition Component에서 직접 작성해도 됩니다. Condition이 부모이고, Chart가 자식 컴포넌트이기 때문에 크게 상관은 없습니다. 다만, 이렇게 작상할 경우 차트 컴포넌트에서 컨디션 컴포넌트의 맴버에 접근할 수 있도록 해줘야 합니다. 아니면, @Output 데코레이터가 지정된 속성에 EventEmitter 인스턴스를 사용합니다. RxJS가 제공하는 Subject 클래스를 확장한 클래스입니다.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.