Page tree
Skip to end of metadata
Go to start of metadata

 

모듈

1) 단일 모듈의 취약점

  • AppModule에 관련도가 떨어지는 모든 요소가 등록되어 관리의 어려움 야기
  • 네임 스페이스 문제 -> 충돌
  • 모듈 단위 지연 로딩 불가 -> 불필요한 요소까지 모두 컴파일하여 최초 화면 렌더링 속도가 느려짐

* 모듈 분리 목적: AppModule이 임포트하는 역할만 맡도록 하여 구조 안정화 + 요소 추가 및 삭제시, 다른 모듈에 영향을 주지 않기 위해.

2) 모듈 종류

  • 기능 모듈: 관련 기능/ 목적/ 페이지 기준

     

    @NgModule({
      ...
      imports: [
        /*Angular Modules, browerserModule 내에 commonModule 포함*/
        BrowserModule, FormsModule, HttpModule,
    
        /*App Modules*/
        ProductModule, CategoryModule
      ],
      ...
    })

    * 해당 기능에 연관된 모듈만 수정

  • 공유 모듈: 여러 모듈에서 사용하는 모듈
  • 핵심 모듈: 최초 부트스트래핑때 사용 + AppComponent 제외하고 전역적으로 사용되는 모든 요소


    import { NavbarComponent } from './navbar/navbar.component';
    import { SidebarComponent } from './sidebar/sidebar.component';
    import { FooterComponent } from './footer/footer.component';
    
    @NgModule({
      imports: [CommonModule],
      declarations: [NavbarComponent, SidebarComponent, FooterComponent]
    })
    export class ScmMainModule { }

 

3) 모듈 imports/ exports

내부에서만 사용할 요소는 imports, 외부에 노출할 요소, 공유할 요소는 모두 exports로 관리.

 


@NgModule({
  	imports: [CommonModule],
  	declarations: [NavbarComponent, SidebarComponent, FooterComponent],
	exports: [NavbarComponent, SidebarComponent, FooterComponent]
})
export class ScmMainModule { }

 

 


라우터

 

  • 뷰 전환
  • 주어진 URL에 매칭되는 컴포넌트를 선택하여 제공 

 

1) 라우터 설정: Route

export interface Route {
  path?: string;
  pathMatch?: string;
  matcher?: UrlMatcher;
  component?: Type<any>;
  redirectTo?: string;
  outlet?: string;
  canActivate?: any[];
  canActivateChild?: any[];
  canDeactivate?: any[];
  canLoad?: any[];
  data?: Data;
  resolve?: ResolveData;
  children?: Routes;
  loadChildren?: LoadChildren;
}


위 정보 중 필수 정보는

  • URL 경로 (=path)
  • URL 매칭 후 할 일 (=component 등록)
  • URL 매칭 방법 (특별한 매칭 방법을 사용하는 경우)

// 기본
{path: 'abc/test', component: AComponent}
{path: 'abc', children: [
	{path: 'test', component: AComponent}
]}
 
// 리다이렉트
{path: '', redirectTo: 'default', pathMatch: 'full'}
 
// 매칭 x
{path:'**', component: PageNotFoundComponent}

 

2) Routes 등록

정의한 Route는 RouterModule에 등록하여 사용. RouterModule은 배열 타입의 Route만 받음.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from "@angular/router";

//import { CommonModule } from '@angular/common';
import { PageNotFoundComponent } from "../scm-main/page-not-found/page-not-found.component";
import { MainDashboardComponent} from "../scm-main/main-dashboard/main-dashboard.component";

const routes: Routes = [
{ path: 'total-summary', canActivate: [], component: MainDashboardComponent},
{ path: '', redirectTo: 'total-summary', pathMatch: 'full'},
{ path: '**', component: PageNotFoundComponent}
];

@NgModule({
imports: [
//CommonModule,
RouterModule.forRoot(routes)],
exports: [RouterModule]})

export class AppRoutingModule { }

 

3) Router Outlet

등록 완료한 뷰가 어느 위치에 렌더링될지 설정.

<scm-navbar></scm-navbar>
<div class="container-fluid">
  <div class="row">
    <scm-sidebar></scm-sidebar>
    <main class="col-10 offset-2 pt-3" [ngSwitch]="currentMenu">
      <router-outlet></router-outlet>
    </main>
  </div>
</div>
<scm-footer></scm-footer>

 

4)  RouterLink, RouterLinkActive

실제 뷰 전환은 두 지시자를 사용하여 이뤄짐.

<a routerLink = "abc/test" routerLinkActive = "active"> A 컴포넌트로 이동! </a>

a 태그의 href 속성을 이용할 경우, 서버에 지속적으로 리소스를 요청하게 되고 그 결과 앵귤러 애플리케이션도 초기화됨.

-> routerLink 지시자를 활용하면 새로운 요청을 하지 않고 브라우저의 history.pushState API를 사용하여 초기화없이 URL만 변경함.

-> 현재 브라우저 URL 경로가 routerLink에 선언된 경로와 동일한 경우, routerLinkActive가 선언된 DOM에 클래스 속성을 선언할 수 있음.

 

5) 라우터를 활용한 상태 관리

  • URL 경로 (path variable)
    - 선언: 특정 패스는 콜론 사용

    const routeA = {path: 'products/:prodNo/options/:optionNo,
    	component: OptionDetailComponent};

    - routerLink 지시자로 값 전달

    <a routerLink = "product/{{prod.no}}/options/{{prod.options[0].no}}">옵션 보기</a>

    - Router 클래스 활용하여 값 전달

    this.router.navigate(['products', prod.no, 'options', prod.options[0].optNo]);

    - 사용하기 위해 조회할 때: ActivatedRoute의 snapshot 활용

    // 생성자에 ActivatedRoute 주입
    constructor(private route: ActivatedRoute){}
     
    ngOnInit(){
    	const params = this.route.snapshot.params;
    	const prodNo = params.prodNo;
    	const optionNo = params.optionNo;	
    }
  • 쿼리스트링
    - 값 전달

    <a routerLink="product" [queryParams]="{key: prod.$key}">{{prod.name}}</a>
    this.router.navigate(['product'], {queryParams: {key: $key}});

     - 조회

    ngOnInit() {
    	const queryParams = this.route.snapshot.queryParams;
    	const $key = queryParams.$key;
    }

6) Router 클래스

뷰의 전환, URL과 관련된 여러 기능을 제공하는 클래스.

  • 뷰 전환 메소드

    navigateByUrl(url: string|UrlTree, extras?: NavigationExtras) : Promise<boolean>
    navigate(commands: any[], extras?: NavigationExtras) : Promise<boolean>
    // url 정보를 어떤 타입으로 받을지를 제외하고는 동일한 기능
    import {Router} from "@angular/router";
     
    export class SomeComponent {
    	constructor(router: Router){ } // 반드시 생성자 선언하여 Router 주입 필요
     
    	moveToOtherView() {
    		this.router.navigate(['products', prod.no, 'test']);
    	}
    }

7) ActivatedRoute 클래스

현재 활성화된 컴포넌트의 라우터 상태 정보를 제공하는 클래스. 제공되는 데이터는 모두 Observable로 제공함.

  • params
  • queryParams
  • data : 뷰가 렌더링되기 전에 필요한 데이터
  • fragment : # 정보
  • url

    constructor(private route: ActivatedRoute) {}
     
    ngOnInit() {
    	this.route.params.subscribe(p => {...});
    }

    * 특정한 시점의 상태를 조회할 때는 snapshot 속성 활용

8) 가드 설정

뷰의 전환 전후에 필요한 로직을 포함할 수 있도록 제공된 인터페이스.

  • CanActivate 가드: 접근 권한 컨트롤시 사용.

  • CanActivateChild 가드: 접근 권한을 보다 세밀하게 컨트롤시 사용.
  • CanLoad 가드: 모듈 자체가 로드되기 전에 접근 제한을 확인하는 용도. 모듈 요소를 컴파일하기 전에 권한 여부 확인하여 권한이 없을 경우 모듈 자체를 컴파일하지 않음. -> 컴파일은 호출 시점에 이뤄짐 (lazy loading)
  • Resolve 가드: 뷰가 실행되기 전에 뷰에서 필요한 데이터를 미리 로딩할 때 사용.
  • CanDeactivate 가드: 현재 노출되고 있는 뷰에서 다른 뷰로 전환하기 전 실행.

 

9) Router 사용시 장점

  • 뷰 전환과 관련된 기능은 라우터에 모두 위임하여 컴포넌트가 뷰의 렌더링과 이벤트 핸들링에만 집중 가능
  • 각 뷰의 상태를 URL로 정의 -> 보다 구체적인 url을 사용하는 Deep Linking (https://en.wikipedia.org/wiki/Deep_linking)

 

10) 라우터 설정 분리

 

 

 

 

 

ES6

 

ES6란

 

ECMA Script 6, ECMA Script 2015 라고도 불리우는 자바스크립트의 표준

 

지원브라우저

http://kangax.github.io/compat-table/es6/

 

References

https://developer.mozilla.org/ko/docs/Web/JavaScript

 

New Features: Overview & Comparison

http://es6-features.org/

  • const

    Const
    const CONST_STRING = "hello";
    const CONST_NUMBER = 1234;
    const CONST_OBJECT = {};
    
    console.log(CONST_STRING);
    console.log(CONST_NUMBER);
    console.log(CONST_OBJECT);
    
    // 에러
    //CONST_STRING = "world";
    //CONST_NUMBER = 5678;
    //CONST_OBJECT = { a: 1 };  
    
    // 허용
    CONST_OBJECT.Name = "warnee";
    console.log(CONST_OBJECT);
    console.log(CONST_OBJECT.Name);
    
    
    // 에러
    //const CONST_STRING = "1";
    {
        // 하지만!!!!
        const CONST_STRING = "2";
        console.log(CONST_STRING);
    }
    console.log(CONST_STRING);
    
    
  • block scope 

    Block Scope
    var a = 1;
    console.log(a);
    {
        var a = 2;
        console.log(a);
    }
    
    {
        var a = 3;
        console.log(a);
    }
    console.log(a); // 엥????
    
    
    let b = 1;
    console.log(b);
    {
        let b = 2;
        console.log(b);
    }
    
    {
        let b = 3;
        console.log(b);
    }
    console.log(b);
    
    console.log("------------------------");
    
    function foo () {
        return 1;
    }
    console.log('35 : ' + foo());
    
    function temp_1() {
        function foo() { return 2; }
        return foo();
    }
    
    {
        // 요건 안되네요.
        function foo() { return 22; }
        console.log('44 : ' + foo());
    }
    
    // function foo () { return 3; }
    // console.log('49 : ' + foo());
    
    function temp_2() {
        return foo();
    }
    
    console.log('53 : ' + foo());
    console.log(temp_1());
    console.log(temp_2());
    
    
  • arrow function

     

    Arrow Function
    function f_0 (a) {
        console.log(a);
    }
    f_0(1);
    
    var f_1 = function (a) {
        console.log(a);
    }
    f_1(2);
    
    function f_2 (a) {
        return v + 1;
    }
    
    var input = [1,3,5,7,9];
    
    var out = input.map(function (v) {
        return v + 1;
    });
    console.log(out);
    
    var out2 = input.map((v) => { return v + 2; });
    console.log(out2);
    
    var out3 = input.map((v) => v + 3);
    console.log(out3);
    
    
    input.forEach(v => {
        console.log(v);
    });
    
    
  • default value

     

    default value
    function temp_1 (a) {
        console.log(a);
    }
    
    temp_1();
    
    console.log('-----------------');
    function temp_2 (a, b = 3) {
        console.log(a + ":" + b);
    }
    
    temp_2();
    temp_2(1);
    temp_2(1,2);
    temp_2(1, null); // !! null 은 값입니다.
    temp_2(1, undefined);
    
    console.log('-----------------');
    function temp_3 (a = 4, b) {
        console.log(a + ":" + b);
    }
    temp_3();
    temp_3(1);
    temp_3(1,2);
    
    
  • spread operator

     

    Spread Operator
    function temp (a, b, ...c) {
        console.log(a + ":" + b + ":" + c);
    }
    
    temp(1, 2, 3);
    temp(1,2,3,4,5);
    temp(1,2,[3,4,5]);
    
    console.log("------------");
    temp(1,2);
    
    function temp2 (a,b,c) {
        console.log(a + ":" + b + ":" + c);
    }
    
    temp2(1,2);
    temp2(1,2,3,4,5);
    temp2(1,2,[3,4,5]);
    
    
  • template

     

    Template
    var tempString = 'hello';
    tempString += '\r\nworld';
    
    console.log(tempString);
    
    var newTempString = `Hello
    World
    !!`;
    console.log(newTempString);
    
    
    
    let id = 'warnee';
    let name = '정태원';
    
    let hello = `Hello ${name} as ${id}`;
    console.log(hello);
    
    
    const warneeSon = {
        Name : "정휘원",
        Age : 7
    }
    
    console.log(`내 아들은 ${warneeSon.Name} 이고 ${warneeSon.Age}살이야`);
    console.log(`내년에 ${warneeSon.Age + 1}살 이라 초등학교 입학해`);
    
    
  • property

     

    Property
    let x = 0;
    let y = 10;
    
    let obj = {x,y};
    
    console.log(obj);
    
    let calc = {
        plus (a, b) { return a + b; },
        minus (a, b) { return a - b; },
    }
    
    console.log(calc);
    console.log(calc.plus(1,2));
    console.log(calc.minus(1,2));
    
    
  • export / import

     

    export / import
    import * as m_1 from "./e_i_module_1"
    console.log(m_1.amount);
    console.log(m_2.discount());
    
    
     
    export var amount = 10
    export function discount() {
        return 9;
    }
    
    
    
  • Class

     

    Class
    class Person {
        constructor (name, birthday) {
            this.name = name;
            this.birthday = birthday;
            this.x = 0;
            this.y = 0;
        }
        move (x, y) {
            this.x += x;
            this.y += y;
        }
    }
    
    const warnee = new Person('정태원', '1976');
    console.log(warnee);
    warnee.move(10, 20);
    console.log(warnee);
    warnee.move(10, 10);
    console.log(warnee);
    
    console.log("-------------------------");
    const warneeSon = new Person('정휘원', '2011');
    console.log(warneeSon);
    warneeSon.move(100, 200);
    console.log(warneeSon);
    
    
    


 

 

 

  • No labels