Category Archives: TypeScript

[Angular2] DOMSanitizer by Pipe

innertHTML등으로 string의 내용을 html DOM 에 바인딩 할때,  스크립트 공격 등을 방어하기 위해 Angular2는 DOMSanitizer를  제공한다.

이를 pipe형태로 간단하게 템플릿에서 사용하기 위해 아래와 같이 처리했다.

import {Pipe, PipeTransform} from "@angular/core";
import {DomSanitizer} from "@angular/platform-browser";

@Pipe({name: "safeHtml"})
export class SafeHtmlPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {
    }

    transform(value: string) {
        return this.sanitized.bypassSecurityTrustHtml(value);
    }
}

@Pipe({name: "safeCss"})
export class SafeCssPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {
    }

    transform(value: string) {
        return this.sanitized.bypassSecurityTrustStyle(value);
    }
}

@Pipe({name: "safeScript"})
export class SafeScriptPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {
    }

    transform(value: string) {
        return this.sanitized.bypassSecurityTrustScript(value);
    }
}

@Pipe({name: "safeResourceUrl"})
export class SafeResourceUrlPipe implements PipeTransform {
    constructor(private sanitized: DomSanitizer) {
    }

    transform(value: string) {
        return this.sanitized.bypassSecurityTrustResourceUrl(value);
    }
}

 

[Angular2] RouterOutlet 의 부모 정보 가져오기

는 바로 Host 데코레이터를 사용하면 됩니다.

constructor (
        @Host() private parent: ParentComponent) { }
    
    
    ngOnInit() {
        console.log(this.parent.category)
    }

Host 데코레이터는 현재 컴포넌트에서 host를 선언한 엘리먼트가 닿을 때까지 의존성 트리를 뒤지면서,

이와 일치하는 의존성을 가진 인젝터를 가져옵니다.

router-outlet을 썼을 경우, 부모 – 자식 관계를 갖기 때문에 이런식으로 부모의 값을 가져올 수 있습니당

 

 

[Angular2, Typescript…] json결과를 Model 객체로 Serialize하기

Angular2, Typescript 와만 관련이 있다고 볼순 없지만..

보통 api서버를 통해서 결과를 json객체로 가져돈다.

그 json객체를 typescipt에서 선언한 모델 객체로 변환하는 방법을 적어본다.

 

일단 이렇게  api결과가 왔고

{
    "id": 1,
    "name": "안녕",
    "created_at": "2015-10-07T11:42:17.000+09:00",
    "updated_at": "2016-04-29T11:15:28.000+09:00",
    "blocked": false,
    "show": true,
    "order": null
}

이 Test 객체에 담아 보자.

export class Test {
  id: number;
  name: string;
  blocked: boolean;
  show: boolean;
  order: number;
  created_at: Date;
  updated_at: Date;
}

모델에 이런 메소드를 만들자.

이 메소드는 object assign을 이용하여 any객체를 test 모델에 할당할 것이다.

그리고 created_at, updated_at이 있다면 이를 Date로 변환할 것이다.

참고로 http 는 import {Http } from “@angular/http”;

요거다.

static fromJSON(obj: any) {
        return Object.assign(new Test(), obj, {
            created_at: obj.created_at && new Date(obj.created_at as string),
            updated_at: obj.updated_at && new Date(obj.updated_at as string)
        });
    }

이제 웹 Api에서  serialize 하자

test() {
        return this.http.post(`/this/is/test/url`)
            .toPromise()
            .then(a => Test.fromJSON(a.json()))
    }

요렇게 하자.

리스트 형태로 날라오면 아래와 같이 하자.

test() {
        return this.http.post(`/this/is/test/url`)
            .toPromise()
            .then(r => (<any[]>r.json()).map(json => Test.fromJSON(json)))
    }

 

 

 

[Angular2] MaxLength Directive

HTML5의 maxlength는 복사 붙여넣기를 할 경우에 해당 길이를 초과할 경우 붙여넣기가 되지 않는다. (500자만큼 잘라서 넣어주지 않는다)

그래서 maxLength 디렉티브를 직접 구현해보기로 했다.

 

input-maxlength.directive.ts

import { NgModel } from '@angular/forms/src/directives';
import { EventEmitter, Output } from '@angular/core';
import {
    Directive,
    ElementRef,
    HostListener,
    Input,
    OnChanges,
    Renderer,
} from '@angular/core';

@Directive({ 
    selector: '[inputMaxLength]',
    host: {
        "(input)": 'onInputChange($event)'
    },
})

export class InputMaxLengthDirective{

    constructor(private el: ElementRef, 
                private renderer: Renderer) { }
    
    @Input('inputMaxLength') inputMaxLength: number;
    @Output() ngModelChange:EventEmitter<any> = new EventEmitter()

    onInputChange($event: any) {
        let text = $event.target.value
        if (text.length > this.inputMaxLength) {
            this.ngModelChange.emit(text.substr(0, this.inputMaxLength))
            this.el.nativeElement.value = text.substr(0, this.inputMaxLength)
        }
    }
}

 

사용예제

<textarea [(ngModel)]="text" [inputMaxLength]="500"></textarea>

 

과정 중에서 몇가지 삽질이 있었는데,  단순히  nativeElement로 제어 할 경우에는, 그에 바인딩 된 model이 제대로 컨트롤 되지 않는 다는 것이다.

그래서 ngModelChange를 불러와서 model에 substr된 값을 emit 했다.

 

[Angular2/Typescript] Fragment 받아오기

export class Sample implements OnInit {
  id: Observable<string>;

  constructor(private route: ActivatedRoute) { }

  ngOnInit(): void {
    this.id = this.route.fragment.map(fragment => fragment)
  }

}

ActivatedRoute 값은 async하게 오기 때문에 저렇게 받아줘야 한다

이제 저 값을 toPromise를 써서 받아올 수도 있고

this.id.toPromise().then(value => { // 어쩌고... } )

view에서는 async 파이프로 가져올 수 있다.

{{ id | async }}

activatedroute는 routing에 관한 각종 정보가 있기 때문에 한 번 주의깊게 볼만하다.