ทำความรู้จัก Component ให้ลึกกัน ตอน 1 (metadata)

Supagrid Tangsermsit
Angular in Thailand
4 min readSep 24, 2017

Component หัวใจหลักของ Angular ซึ่ง component เป็น Decorator ตัวชนิดหนึ่งใน Angular โดยที่ ความสามารถบางส่วนได้เป็นความสามารถของ Directive (Component inherited from Directive) สำหรับ metadata ของ component มีดังนี้

selector

selector?: string

selector หรือคือชื่อของ component หรือ directive โดยการกำหนดชื่อจะอ้างอิงถึงการสร้างแบบ css นั้นหมายความว่าเราสามารถกำหนดชื่อด้วย คำสั่งแบบ css ได้เลย

  • element-name : กำหนด selector เป็น tag html อย่าง app-cat หรือ app-dog
  • .class : กำหนด selector เป็นชื่อ class
  • [attribute] : กำหนด selector เป็นชื่อ attribute
  • [attribute=value] : กำหนด selector เป็นชื่อ attribute พร้อม value
  • :not(sub_selector): กำหนดเมื่อ selector ไม่ตรงกับ sub_selector
  • selector1, selector2 : เลือกใช้เมื่อตรงกับ selector1 หรือ selector2

template และ templateUrl

template?: stringtemplateUrl?: string

สำหรับ component จะต้องมีการกำหนด template เอาไว้ใช้อ้างอิงถึงหน้าตาของ component นั้น ซึ่ง template คือ tag html โดย template เป็น html ที่เป็น string และ templateUrl ที่อ้างอิงถึงไฟล์ html ให้เลือกใช ้template หรือ templateUrl อย่างใดอย่างหนึ่ง

styles และ styleUrl

styles?: string[]styleUrl?: string[]

เอาไว้สำหรับกำหนด stylesheet ให้กับ component โดย css ที่กำหนดจะไม่ยุ่งกับ component อื่น แต่สามารถกำหนดให้อ้างอิงถึง component ลูกได้ ซึ่งถ้าใครใช้ angular-cli สามารถกำหนดชนิดของ stylesheet ได้ไม่ว่าจะใช้ css scss หรือ less เป็นต้น จากโค้ดข้างล่างกำหนด :host เป็นตัวอ้างอิงถึง Component นี้ และใช้ >>> อ้างอิงถึงลูก

Live Demo

animations

animations?: any[]

เอาไว้สำหรับกำหนด Animation ของ Component นี้ จากตัวอย่างข้างล่างจะกำหนด event click ให้กับ button เมื่อ click จะสลับจากสีแดงเป็นสีฟ้าและให้ 0.5 วินาทีสำหรับเริ่มและ 0.5 วินาทีสำหรับจบ animation

Live Demo

encapsulation

encapsulation?: ViewEncapsulation

เอาไว้กำหนดวิธีที่ template และ stylesheet จะถูกคลุมด้วยวิธีดังนี้

ViewEncapsulation.Native

กำหนดให้ Component ใช้การแสดงผลแบบ Shadow DOM ซึ่ง Browser ต้องรองรับ Shadow DOM ด้วย ซึ่ง Shadow DOM จะสร้าง Element พิเศษขึ้นมาครอบ Component อย่างรูปด้านล่างจะสร้าง #shadow-root และประกาศ <style></style> ที่ใช้เอาไว้ข้างใน รวมถึง html จาก Component นั้นด้วย

Live Demo

ViewEncapsulation.Emulated

Emulated ถือเป็นค่าเริ่มต้นของ encapsulation โดยหลักการทำงานของ emulated จะ preprocess css เอาไว้ก่อนโดยจะใช้ชื่อของ attribute เป็นตัวอ้างอิงถึง Component นั้น ๆ ตัวอย่างรูปด้านล่าง Angular จะประกาศ attribute ชื่อ ngcontent-c0 เพื่อให้ css อ้างอิงถึงแค่ html ทีอยู่ภายใน Component นี้เท่านั้น

Live Demo

ViewEncapsulation.None

จาก 2 ตัวเลือกด้านบนนั้นเราจะสามารถกำหนด css ให้ใช้เฉพาะกับ Component ที่เป็นเจ้าของ css ได้ แต่ถ้าเรากำหนด None หลักการทั้งหมดจะใช้ไม่ได้ หมายความว่า ถ้ากำหนด css ให้กับ Component นั้น css ของเราจะกลายเป็น css แบบ global ทั้นที เป็นเพราะเราปิดการใช้งาน encapsulation นั้นเอง

live demo

inputs และ outputs

inputs?: string[]
outputs?: string[]

เป็นการระบุ Inputs และ Outputs สำหรับ Component นั้นเหมือนกับใช้ “@Input” และ “@Output” ซึ่งจากรูปด้านล่างกำหนด Input คือ first_name และ last_name และ กำหนด Output คือ count$ เมื่อ click button จะส่งค่า count + 1 ไปที่ Component แม่แล้วแสดงจำนวน count ออกมา

Live Demo

host

เอาไว้เพื่อระบุ event, action, properties และ attributes ที่เกี่ยวข้องกับ Component นี้ จากโค้ดข้างล่างได้กำหนด event click (ใช้ “@HostListener” ได้เช่นกัน) และกำหนด class odd แล even พร้อมทั้งกำหนด attribute data-attr ด้วย (ใช้ “@HostBinding” ได้เช่นกัน)

Live Demo

exportAs

เป็นตัวกำหนดชื่อของ Component เพื่อสามารถเข้าตัวแปรหรือฟังก์ชันของ Component นี้ได้ จากตัวอย่างด้านล่าง กำหนด MyExportAsComponent ชื่อ myExport และใน template ของ App มีการประกาศ #me=”myExport” เพื่อสามารถเข้าถึง MyExportAsComponent ได้ใน template นี้

Live Demo

providers

เอาไว้สำหรับกำหนดชุดของ Class ที่จะเป็น Inject เพื่อเอามาใช้ใน Component นี้รวมถึง Component ลูกด้วย

queries

queries?: {[key: string]: any}

กำหนด query ทีี่จะ inject เข้ามาที่ Component ซึ่ง content จะถูก set ก่อน “ngAfterContentInit” ส่วน view จะถูก set ก่อน “ngAfterViewInit”

Live Demo

interpolation

interpolation?: [string, string]

เปลี่ยนแปลงค่าเริ่มต้นของตัว encapsulation โดยค่าเริ่มต้นตัวเปิดคือ “{{” และตัวปิดคือ “}}” จากโค้ดข้างล่างแทนตัวเปิดคือ “((” และ ตัวปิดคือ “::” นั้นคือใช่ “((name::” แทน “{{name}}”

entryComponents

entryComponents?: Array<Type<any>|any[]>

กำหนด Component ที่จะถูก compile ไปพร้อมกับ Component นี้เมื่อถูกประกาศใช้ โดย Component ใน entryComponents

Live Demo

changeDetection

changeDetection?: ChangeDetectionStrategy

เอาไว้ระบุชนิดของ change detection ที่จะใช้ใน Component นั้น

ChangeDetectionStrategy.Default

เป็นการบอกว่า Component ให้ตรวจสอบและเปลี่ยนแปลง template เมื่อมีค่าเปลี่ยนแปลงเสมอ ซึ่งเป็นค่าเริ่มต้นของ Component อยู่แล้ว

ChangeDetectionStrategy.OnPush

เป็นการบอก Component ให้ตรวจสอบและเปลี่ยนแปลง template เมื่อมีการกำหนดให้ทำ จากโค้ดด้านล่าง จะทำการเปลี่ยนค่า count ที่แสดงใน template ก็ต่อเมื่อ count หารด้วย 5 ลงตัว แล้วทำการบอก change detection ด้วยคำสั่ง “markForCheck()” เพื่อบอกให้ change detection ตรวจสอบค่าและเปลี่ยนค่าใน template

Live Demo

viewProviders

viewProviders?: Provider[]

เอาไว้สำหรับกำหนดชุดของ Class ที่จะเป็น Inject เพื่อเอามาใช้ใน Component ลูก

Live Demo

preserveWhitespaces

preserveWhitespaces?: boolean

เมื่อกำหนด preserveWhitespaces: false เมื่อเข้าสู่การ Compile จะเป็นการลบ whitespace ออก สิ่งนี้ช่วยให้ การ build แบบ AOT ประหยัดขนาดของไฟล์ได้มากขึ้น

  • whitespace ทั้งหมดที่หัวและท้ายของ template จะถูกลบออก
  • whitespace ข้างหน้า tag จะถูกลบ (<div>text 1</div> <div>text 2</div> เป็น <div>text 1</div><div>text 2</div>)
  • หลาย whitespace จะถูกลบเหลือแค่ 1 whitespace (<div>\n text \n</div> เป็น <div> text </div> )
  • whitespace ที่อยู่ไหน tag บาง tag จะไม่ถูกลบออก (เช่น <pre> หรือ <textarea>)
  • ใช้ ngPreserveWhitespaces ป้องกันการถูกลบ whitespace ได้
  • ใช้ &nbsp; ในการกำหนด whitespace แต่ ถ้ากำหนดหลาย &nbsp; จะถูกลบออกเหลือแค่ 1

--

--

Supagrid Tangsermsit
Angular in Thailand

Frontend Developer ผู้ใฝ่ฝันอยากทำร้านขนมปัง