Ember.js: [META] 자수 μ€€λΉ„

에 λ§Œλ“  2020λ…„ 08μ›” 18일  Β·  17μ½”λ©˜νŠΈ  Β·  좜처: emberjs/ember.js

μ˜€λŠ˜λ‚  Embroider in compatibility modeλŠ” μƒˆλ‘œμš΄ μ‘μš© ν”„λ‘œκ·Έλž¨κ³Ό λ§Žμ€ κΈ°μ‘΄ μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. splitAtRoutes λͺ¨λ“œμ˜ 이점을 μ–»κΈ° μœ„ν•΄ ν•„μš”ν•œ staticComponents λͺ¨λ“œμ—μ„œ Embroiderλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 더 μ–΄λ ΅μŠ΅λ‹ˆλ‹€.

Embroider μ €μž₯μ†Œμ˜ Issue # 501 은 Ember.js 릴리슀의 μΌλΆ€λ‘œ Embroiderλ₯Ό μ•ˆμ •ν™”ν•˜λŠ” 데 ν•„μš”ν•œ λ‚˜λ¨Έμ§€ 문제λ₯Ό μΆ”μ ν•©λ‹ˆλ‹€.

이 λ¬Έμ œλŠ” μ‚¬λžŒλ“€μ΄ 경둜 기반 μ½”λ“œ λΆ„ν•  ( "자수 μ€€λΉ„")κ³Ό ν•¨κ»˜ μ§€μ›λ˜λŠ” μ˜΅μ…˜μœΌλ‘œ Embroider와 ν•¨κ»˜ Emberλ₯Ό μ‹€μ œλ‘œ μ‚¬μš©ν•˜κΈ° 전에 μ·¨ν•΄μ•Ό ν•  단계λ₯Ό μΆ”μ ν•©λ‹ˆλ‹€. Embroiderλ₯Ό μ‚¬μš©ν•˜λŠ” 방법은 μ—¬λŸ¬ 가지가 μžˆμ§€λ§Œ (ꡬ체적인 이점은 거의 μ œκ³΅ν•˜μ§€ μ•Šμ§€λ§Œ 기본적으둜 Ember 자체λ₯Ό Embroider둜 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•˜λŠ” 데 μ€‘μš”ν•œ ν˜Έν™˜μ„± λͺ¨λ“œλ₯Ό ν¬ν•¨ν•˜μ—¬)이 λ¬Έμ œλŠ” 일반 Ember μ‘μš© ν”„λ‘œκ·Έλž¨κ³Ό ν•¨κ»˜ Embroiderλ₯Ό μ‚¬μš©ν•˜κ³  이점을 μ–»λŠ” κΈ°λŠ₯에 쀑점을 λ‘‘λ‹ˆλ‹€. 경둜 기반 μ½”λ“œ λΆ„ν• μ—μ„œ.

기술 μš”κ΅¬ 사항

Embroider README에 μ„€λͺ… λœλŒ€λ‘œ 경둜 기반 μ½”λ“œ λΆ„ν•  ( splitAtRoutes )을 ν™œμ„±ν™”ν•˜λ €λ©΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ λ‹€μŒ ν”Œλž˜κ·Έλ₯Ό ν™œμ„±ν™” ν•  수 μžˆμ–΄μ•Όν•©λ‹ˆλ‹€.

  • [] staticAddonTestSupportTrees
  • [] staticAddonTrees
  • [] staticHelpers
  • [] staticComponents

μ• λ“œμ˜¨ λ˜λŠ” μ‘μš© ν”„λ‘œκ·Έλž¨μ΄ μ΄λŸ¬ν•œ ν”Œλž˜κ·Έκ°€μžˆλŠ” μƒνƒœμ—μ„œ μž‘λ™ ν•  μˆ˜μ—†λŠ” 경우 "ν΄λž˜μ‹ 동적 κΈ°λŠ₯"을 μ‚¬μš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

MVP : (component dynamicString) 쀑단 및 ꡐ체

자수 μ€€λΉ„ ( "MVP")의 첫 번째 λͺ©ν‘œλ₯Ό μœ„ν•΄ μ‹€μ œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ 정적 ν”Œλž˜κ·Έλ₯Ό ν™œμ„±ν™”ν•˜λ €κ³  ν•  λ•Œ 발견 ν•œ κ°€μž₯ 일반적인 μž₯애물을 μ œκ±°ν•΄μ•Όν•©λ‹ˆλ‹€.

MVP λ§ˆμΌμŠ€ν†€μ˜ 경우 λͺ¨λ“  μƒνƒœκ³„ μ• λ“œμ˜¨μ΄ μ΄λŸ¬ν•œ ν”Œλž˜κ·Έλ₯Ό μ§€μ›ν•˜λŠ” 것은 λͺ©ν‘œκ°€ μ•„λ‹™λ‹ˆλ‹€ .

λŒ€μ‹ , λͺ©ν‘œλŠ” μ‘μš© ν”„λ‘œκ·Έλž¨μ΄ splitAtRoutes 둜의 합리적인 μ „ν™˜ 경둜λ₯Ό κ°–κ³  ν•΄λ‹Ή λͺ¨λ“œμ—μ„œ μ‹€μ§ˆμ μ΄κ³  μ‚¬μ†Œν•˜μ§€ μ•Šμ€ μ‘μš© ν”„λ‘œκ·Έλž¨μ„ λΉŒλ“œ ν•  수 μžˆλ„λ‘ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 즉, κΈ°λ³Έ Blueprint에 포함 된 λͺ¨λ“  μ• λ“œμ˜¨μ€ ν΄λž˜μ‹ 동적 κΈ°λŠ₯μ—μ„œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•΄μ•Όν•©λ‹ˆλ‹€. λ˜ν•œ Ember λ™μ‹œμ„±κ³Ό 같은 μ‹€μ œ μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ 자주 μ‚¬μš©λ˜λŠ” μ• λ“œμ˜¨μ€ 고전적인 동적 κΈ°λŠ₯을 μ‚¬μš©ν•΄μ„œλŠ” μ•ˆλ©λ‹ˆλ‹€.

staticComponents

이것은 κ°€μž₯ μ€‘μš”ν•œ 정적 ν”Œλž˜κ·Έ 이며 μš”κ΅¬ 사항은 MVP λŒ€μƒμ— κ°€μž₯ 큰 μž₯μ• λ¬Όμ΄λ©λ‹ˆλ‹€.

staticComponents λ₯Ό ν™œμ„±ν™”ν•˜λ €λ©΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ( μ• λ“œμ˜¨ 포함 )μ—μ„œ (component dynamicString) λ₯Ό λͺ¨λ‘ μ‚¬μš©ν•˜μ§€ μ•Šμ•„μ•Όν•©λ‹ˆλ‹€.

μ€‘μš”ν•œ 것은, μ‘μš© ν”„λ‘œκ·Έλž¨ 및 μ• λ“œμ˜¨μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€ (component "static string") 에 staticComponents λͺ¨λ“œ.

μ‹€μ œλ‘œ μ΄λŠ” λ‹€μŒ

{{#let (component this.componentName) as | Component |}}

ν˜„μž¬ 곡용 API의 μΌλΆ€λ‘œ λ¬Έμžμ—΄μ„ μ‚¬μš©ν•˜λŠ” μ• λ“œμ˜¨μ€ λŒ€μ‹  ꡬ성 μš”μ†Œλ₯Ό κ°€μ Έμ™€μ•Όν•©λ‹ˆλ‹€. 즉,이 μ• λ“œμ˜¨μ€ μ‚¬μš©μž κ°€ λ¬Έμžμ—΄μ΄ μ•„λ‹Œ 호좜 ν•  ꡬ성 μš”μ†Œλ₯Ό μ œκ³΅ν•΄μ•Όν•˜λŠ” μ ‘κ·Ό λ°©μ‹μœΌλ‘œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•΄μ•Όν•©λ‹ˆλ‹€.

this.component κ°€ this.componentName = <code i="29">scaffolding/${dasherize(csId!)}/${dasherize(this.args.feature)}</code> 둜 μ •μ˜λ˜κΈ° λ•Œλ¬Έμ— 이것은 특히 μ–΄λ €μš΄ μƒν™©μž…λ‹ˆλ‹€. 이와 같은 상황이 λ°”λ‘œ μš°λ¦¬κ°€ μ „ν™˜ μ „λž΅μ„ μƒκ°ν•˜κ³  μ‹ μ€‘ν•˜κ²Œ μ‹€ν–‰ν•΄μ•Όν•˜λŠ” μ΄μœ μž…λ‹ˆλ‹€.

μ΅œμ†Œν•œ μ• λ“œμ˜¨μ΄ (component dynamicString) μ—μ„œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ ν•  수 μžˆλ„λ‘ν•˜λ €λ©΄ 동적 ꡬ성 μš”μ†Œμ˜ ν˜ΈμΆœμ„ ν—ˆμš©ν•˜μ§€ μ•ŠλŠ” component ν‚€μ›Œλ“œμ˜ μƒˆ 버전을 λ§Œλ“€μ–΄μ•Όν•©λ‹ˆλ‹€.

λ˜ν•œ κΊΎμ‡  κ΄„ν˜Έ ꡬ문을 μ‚¬μš©ν•œ ꡬ성 μš”μ†Œ 호좜이 동적 component ν‚€μ›Œλ“œμ™€ λ™μΌν•œ λ°©μ‹μœΌλ‘œ μž‘λ™ν•˜λ„λ‘ μ‹€μˆ˜λ‘œ ν—ˆμš©ν•˜λŠ” 버그 λ₯Ό μˆ˜μ •ν•΄μ•Όν•©λ‹ˆλ‹€. μ‚¬λžŒλ“€μ΄ (component dynamic) μ—μ„œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•˜κΈ° μ‹œμž‘ν•˜λ©΄ μ‚¬λžŒλ“€μ΄ μ‹€μˆ˜λ‘œ <dynamic> 둜 λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ν•˜κ³  μž‘λ™ν•˜λŠ”μ§€ κ΄€μ°° ν•œ λ‹€μŒ 계속 진행할 κ°€λŠ₯성이 λ†’κΈ° λ•Œλ¬Έμ—μ΄ μž‘μ—…μ€ 곧 μ™„λ£Œλ˜μ–΄μ•Όν•©λ‹ˆλ‹€.

μž‘μ—… ν•­λͺ© :

  • [] 정적 λ¬Έμžμ—΄ 만 μ§€μ›ν•˜λŠ” μƒˆ λ²„μ „μ˜ (component) 섀계 및 μΆœμ‹œ (RFC ν•„μš”)
  • [] κΊΎμ‡  κ΄„ν˜Έ 호좜이 Ember의 동적 ꡬ성 μš”μ†Œ 호좜처럼 λ™μž‘ν•˜λ„λ‘ ν—ˆμš©ν•˜λŠ” 버그 μˆ˜μ • (버그 μˆ˜μ •, μ•„λ§ˆλ„ μΉœλ°€ν•œ API)

staticHelpers

staticHelpers ν”Œλž˜κ·ΈλŠ” Ember ν…œν”Œλ¦Ώμ˜ ν‘œν˜„λ ₯을 κ°μ†Œ μ‹œν‚€μ§€λŠ” μ•Šμ§€λ§Œ, μ‘μš© ν”„λ‘œκ·Έλž¨ λ„μš°λ―Έμ˜ 전체 λͺ©λ‘μ„ λ‘œλ”μ˜ λͺ¨λ“ˆ μ§‘ν•©μ—μ„œ μ‚¬μš©ν•  수 μ—†μŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

이것이 Ember μ‘μš© ν”„λ‘œκ·Έλž¨μ— 영ν–₯을 λ―ΈμΉ  것이라고 κ°€μ •ν•˜μ§€λ§Œ staticComponents 보닀 훨씬 적은 λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. ν˜„μž¬ staticHelpers 이 MVP λŒ€μƒμ— 영ν–₯을 λ―ΈμΉ  κ²ƒμœΌλ‘œ μ˜ˆμƒν•˜μ§€ μ•Šμ§€λ§Œ μ‘μš© ν”„λ‘œκ·Έλž¨μ„ splitAtRoutes 둜 μ—…κ·Έλ ˆμ΄λ“œν•˜λ €κ³  μ‹œλ„ν•¨μ— 따라 λ³€κ²½ 될 수 μžˆμŠ΅λ‹ˆλ‹€. 이 경우 λ¬Έμ œκ°€μžˆλŠ” μ‚¬μš© 사둀λ₯Ό ν‰κ°€ν•˜κ³  λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ„ μš©μ΄ν•˜κ²Œν•˜λŠ” μƒˆλ‘œμš΄ APIλ₯Ό κ³ λ €ν•΄μ•Όν•©λ‹ˆλ‹€.

staticAddonTrees 및 staticAddonTestSupportTrees

ν˜„μž¬ 가정은 μ΄λŸ¬ν•œ ν”Œλž˜κ·Έκ°€ λŒ€λΆ€λΆ„μ˜ κ΄€μš©μ  인 Ember μ•± 및 μ• λ“œμ˜¨κ³Ό ν˜Έν™˜λ˜λ―€λ‘œ MVP λŒ€μƒμ˜ μš”κ΅¬ 사항에 λŒ€ν•΄ μ‹€μ§ˆμ μΈ 문제λ₯Ό μΌμœΌν‚€μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

λ‹€μŒ 단계

이 λ¬Έμ œλŠ” MVP λͺ©ν‘œλ₯Ό 달성 ν•œ 후에도 좔적 문제둜 남아 μžˆμŠ΅λ‹ˆλ‹€. MVP λŒ€μƒ μ΄ν›„μ—λŠ” μ™„μ „ν•œ 에코 μ‹œμŠ€ν…œ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ„ μ΄‰μ§„ν•˜κ³  동적 μ‚¬μš© μ‚¬λ‘€μ˜ 인체 곡학을 κ°œμ„ ν•΄μ•Όν•©λ‹ˆλ‹€ (μ½”λ“œ 뢄할에 λŒ€ν•œ 지원 μœ μ§€). ν…œν”Œλ¦Ώ κ°€μ Έ 였기 λŠ” μ΄λŸ¬ν•œ λͺ©ν‘œλ₯Ό λ‹¬μ„±ν•˜λŠ” 데 도움이 될 수 μžˆμŠ΅λ‹ˆλ‹€.

Help Wanted

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

νŠΈμœ— λ‹΄μ•„ κ°€κΈ°

일반적으둜 μ‚¬λžŒλ“€μ΄ (component dynamicString) λŒ€μ‹ ν•΄μ•Ό ν•  일에 λŒ€ν•΄ μƒκ°ν•˜λŠ” 방법은 μ–΄λ”˜κ°€ 둜 κ°€λ €λ©΄ import λ˜λŠ” (component "staticString") κ°€ ν•„μš”ν•˜λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

μ˜΅μ…˜μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • ꡬ성 μš”μ†Œμ˜ ν˜ΈμΆœμžλŠ” (component "staticString")
  • μ—­ λ™μ„±μ΄μžˆλŠ” μ½”λ“œλŠ” κ°€λŠ₯성을 μ—΄κ±°ν•˜κ³ μ§€λ„μ— λ„£κ³  (get componentMap dynamicString) λ₯Ό μ‚¬μš©ν•˜μ—¬

이제 생각할 수 μžˆμŠ΅λ‹ˆλ‹€. (get components dynamicString) κ°€ (component dynamicString) 보닀 더 λ‚˜μ„ μˆ˜μžˆλŠ” 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? λŒ€λ‹΅μ€ componentMap μ–΄λ”˜κ°€μ— λΉŒλ“œν•΄μ•Όν•˜κ³  κ·œμΉ™μ΄ μž¬κ·€ 적으둜 μ μš©λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

<InputField @type="text" /> λ˜λŠ” <InputField @type="checkbox" /> (예 <input> HTMLμ—μ„œ

input-field λŒ€ν•œ ν…œν”Œλ¦Ώμ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

{{#let (hash text=(component "inputs/text-field") checkbox=(component "inputs/checkbox")) as |components|}}
  {{component (get components @type)}}
{{/let}}

이런 μ‹μœΌλ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ©΄ EmbroiderλŠ” λ²ˆλ“€μ— 두 개의 ꡬ성 μš”μ†Œ 만 ν¬ν•¨ν•˜λ©΄λœλ‹€λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒκ³Ό 같이 μž‘μ„± ν–ˆμŠ΅λ‹ˆκΉŒ?

{{component (concat "inputs/" <strong i="33">@type</strong> "-field")}}

(예, 그런 것듀은 λ†€λžκ²Œλ„ μΌλ°˜μ μž…λ‹ˆλ‹€)

EmbroiderλŠ” μ½”λ“œλ₯Ό μ‰½κ²Œ λΆ„μ„ν•˜κ³  λ²ˆλ“€μ— 포함될 ꡬ성 μš”μ†Œλ₯Ό μ œν•œ ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 당신은 (λ˜ν•œ 맀우 μΌλ°˜μ μ΄λ‹€) μžλ°” μŠ€ν¬λ¦½νŠΈμ—μ„œ 일을 ν•œ κ²½μš°μ— 더 μ•…ν™”μž…λ‹ˆλ‹€ :

export default class extends Component {
  get innerComponent() {
    return `inputs/${this.args.type}-field`;
  }
}

이 ν…œν”Œλ¦ΏμœΌλ‘œ :

{{component this.innerComponent}}

μ•½κ°„μ˜ μ‘°μ •μ΄μ§€λ§Œ Embroiderκ°€ μ‹€μ œλ‘œ μ‚¬μš©λ˜λŠ” ꡬ성 μš”μ†Œλ₯Ό κ²°μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λͺ¨λ“  17 λŒ“κΈ€

μ „ν™˜ λΉ„μš©μ„ μ€„μ΄λŠ” ν•œ 가지 방법은 μ• λ“œμ˜¨μ΄ ꡬ성 μš”μ†Œ ν˜ΈμΆœμžκ°€ μ „λ‹¬ν•œ 정적 λ¬Έμžμ—΄μ— ν•΄λ‹Ήν•˜λŠ” 인수λ₯Ό μ •μ μœΌλ‘œ ν‘œμ‹œν•˜λ„λ‘ ν—ˆμš©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

μŠ€ν•λ³Όλ‘œ ( better-component λŠ” 정적 ꡬ성 μš”μ†Œ ν‚€μ›Œλ“œμ˜ 이름에 λŒ€ν•œ 자리 ν‘œμ‹œ μžμž…λ‹ˆλ‹€).

{{better-component <strong i="8">@arg</strong> staticString=true}}

μ΄λ ‡κ²Œν•˜λ©΄ μ• λ“œμ˜¨μ΄ νŠΉμ • "동적 호좜"이 호좜자 κ°€ 정적 λ¬Έμžμ—΄μ„ μ œκ³΅ν•˜λŠ” κ²½μš°μ—λ§Œ μž‘λ™ 함을 λ‚˜νƒ€λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

λ§Žμ€ 동적 ꡬ성 μš”μ†Œ 사둀가 μ‹€μ œλ‘œ "μ• λ“œμ˜¨μ— 전달 된 λ¬Έμžμ—΄ 인수"둜 인해 λ°œμƒν•˜λŠ” κ²½μš°μ—λ§Œμ΄ μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Όν•©λ‹ˆλ‹€.

이것이이 λ¬Έμ œμ— λŒ€ν•œ 주제라면 Idkμ΄μ§€λ§Œ, λ‚˜λŠ” 주기적으둜 emberclear에 λŒ€ν•œ μ™„μ „ν•œ 정체성을 νŒŒμ•…ν•˜λ €κ³  λ…Έλ ₯ν•˜κ³  있으며 λ¬Έμ œμ™€ 해결책에 λŒ€ν•œ λ¬Έμ„œ 좔적을 μœ μ§€ν•΄ μ™”μŠ΅λ‹ˆλ‹€.

https://github.com/NullVoxPopuli/emberclear/pull/784

κ·Έλ ‡λ‹€λ©΄ μ‚¬λžŒλ“€μ΄ λ¬Έμ œμ— λΆ€λ”ͺ히면 Abe λ¬Έμ„œκ°€ 도움이 될 수 μžˆμŠ΅λ‹ˆκΉŒ? Idk

λ˜ν•œ μžμˆ˜μ— 맀우 ν₯λΆ„ν•˜κ³  있으며, μ™„μ „ν•œ 정적이 λ‹¬μ„±λ˜λ©΄ 이미 큰 κ³„νšμ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€.
https://github.com/emberjs/rfcs/issues/611

우리의 μ‘μš© ν”„λ‘œκ·Έλž¨μ€ 동적 μ½˜ν…μΈ  전달 μ‹œμŠ€ν…œμž…λ‹ˆλ‹€. μ½˜ν…μΈ  μ œμž‘μžλŠ” "ν™œλ™ μš”μ†Œ"μ—μ„œ μ½˜ν…μΈ λ₯Ό μ‘°λ¦½ν•©λ‹ˆλ‹€. 각 μš”μ†Œμ—λŠ” ν•΄λ‹Ήν•˜λŠ” Ember ꡬ성 μš”μ†Œκ°€ 있으며 κ·Έ 이름은 Ember 데이터 λͺ¨λΈμ— μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 이 μ‹œμŠ€ν…œμ˜ 핡심은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

// example model definition
export default class TextElement extends Model {
  _componentName = 'text-element';
}
  {{#each (sort-by "position" @activityElements) as |activityElement|}}
    {{component (get activityElement "_componentName")}}

μœ„ λ‚΄μš©μ„ μ½μ—ˆμ„ λ•Œ 이것이 (component dynamicString) μ‹œλ‚˜λ¦¬μ˜€μž„μ„ μ‹œμ‚¬ν•©λ‹ˆλ‹€. μ •ν™•ν•©λ‹ˆκΉŒ?

μœ„μ˜ λ‚΄μš©μ„ μ½μ—ˆμ„ λ•Œ 이것이 (ꡬ성 μš”μ†Œ dynamicString) μ‹œλ‚˜λ¦¬μ˜€μž„μ„ μ‹œμ‚¬ν•©λ‹ˆλ‹€. μ •ν™•ν•©λ‹ˆκΉŒ?

@activityElements 은 무엇이며 어디에 μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆκΉŒ?

이것은 컨트둀러 ꡬ성 μš”μ†Œμ— 전달 된 Ember 데이터 λͺ¨λΈ μΈμŠ€ν„΄μŠ€μ˜ λ°°μ—΄μž…λ‹ˆλ‹€.

λ˜ν•œ 동적 ꡬ성 μš”μ†Œ FYI에 μ•½κ°„μ˜ 투자λ₯Όν–ˆμŠ΅λ‹ˆλ‹€. μž‘λ…„μ— https://discuss.emberjs.com/t/the-perils-of-dynamic-component-invocation/16784 μ—μ„œ 여기에 λŒ€ν•΄ λ¬Όμ—ˆμŠ΅λ‹ˆλ‹€

μš°λ¦¬λ„ 그래. μš°λ¦¬λŠ” 말 κ·ΈλŒ€λ‘œ μ•±μ—μ„œ μ‚¬μš©ν•  ꡬ성 μš”μ†Œλ₯Ό 미리 μ•Œμ§€ λͺ»ν•©λ‹ˆλ‹€. λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯λ˜μ–΄ (λ¬Όλ‘  λ³€κ²½ κ°€λŠ₯ν•˜κ²Œ 함) λ°±μ—”λ“œμ—μ„œ 컴파일되고 μš”μ²­μ‹œ ν”„λŸ°νŠΈ μ—”λ“œλ‘œ μ „μ†‘λ©λ‹ˆλ‹€. 우리λ₯Ό μœ„ν•΄ 동적 component λ„μš°λ―Έλ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€λŠ” 것은 배열에 λŒ€ν•΄ for-eachλ₯Ό μˆ˜ν–‰ ν•  μˆ˜μ—†λŠ” 것과 κ°™μŠ΅λ‹ˆλ‹€. λ‚˜λŠ” μ •λ§λ‘œ 이와 같은 μ‚¬μš© 사둀에 λŒ€ν•΄ μ•žμœΌλ‘œ λ‚˜μ•„κ°ˆ 방법이 있기λ₯Ό λ°”λžλ‹ˆλ‹€. ν•„μš”ν•œ μ—­ 동성이 μ—†κΈ° λ•Œλ¬Έμ— λ‚΄ 앱이 μž‘λ™ν•˜μ§€ μ•ŠμœΌλ©΄ μ½”λ“œ λΆ„ν•  / 트리 흔듀림에 λŒ€ν•΄ ν™•μ‹€νžˆ μ‹ κ²½ 쓰지 μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€.

ν•΄λ‹Ή μ‹œλ‚˜λ¦¬μ˜€μ— μœ νš¨ν•œ λͺ¨λ“  ꡬ성 μš”μ†Œμ˜ 맡을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

예λ₯Ό λ“€λ©΄ :

{{#let (hash
   Foo=(import 'path/to/foo')
   Etc=...
) as |validComponents|
}}
  {{component (get validComponents @someDynamicValue)}}
{{/let}}

?

λ§ˆμ°¬κ°€μ§€λ‘œ, μ•±μ—μžˆλŠ” ν•­λͺ© 만 λ Œλ”λ§ ν•  수 있기 λ•Œλ¬Έμ— 전체 동적 ꡬ성 μš”μ†Œλ₯Ό κ°€μ§ˆ 수 μ—†μŠ΅λ‹ˆλ‹€. λ Œλ”λ§ ν•  ν•­λͺ©μ„ μ„ νƒν•˜λŠ” λͺ©λ‘μ„ λ§Œλ“œλŠ” 것도 디버깅에도 λ„μ›€μ΄λ©λ‹ˆλ‹€. "μ•„,이 값은 μœ νš¨ν•œ ꡬ성 μš”μ†Œ 쀑 ν•˜λ‚˜κ°€ μ•„λ‹™λ‹ˆλ‹€."

ν•΄λ‹Ή μ‹œλ‚˜λ¦¬μ˜€μ— μœ νš¨ν•œ λͺ¨λ“  ꡬ성 μš”μ†Œμ˜ 맡을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?

이것은 ν™•μ‹€νžˆ 우리의 μ‚¬μš© 사둀λ₯Ό λ‹€λ£° κ²ƒμž…λ‹ˆλ‹€.

νŠΈμœ— λ‹΄μ•„ κ°€κΈ°

일반적으둜 μ‚¬λžŒλ“€μ΄ (component dynamicString) λŒ€μ‹ ν•΄μ•Ό ν•  일에 λŒ€ν•΄ μƒκ°ν•˜λŠ” 방법은 μ–΄λ”˜κ°€ 둜 κ°€λ €λ©΄ import λ˜λŠ” (component "staticString") κ°€ ν•„μš”ν•˜λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

μ˜΅μ…˜μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • ꡬ성 μš”μ†Œμ˜ ν˜ΈμΆœμžλŠ” (component "staticString")
  • μ—­ λ™μ„±μ΄μžˆλŠ” μ½”λ“œλŠ” κ°€λŠ₯성을 μ—΄κ±°ν•˜κ³ μ§€λ„μ— λ„£κ³  (get componentMap dynamicString) λ₯Ό μ‚¬μš©ν•˜μ—¬

이제 생각할 수 μžˆμŠ΅λ‹ˆλ‹€. (get components dynamicString) κ°€ (component dynamicString) 보닀 더 λ‚˜μ„ μˆ˜μžˆλŠ” 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ? λŒ€λ‹΅μ€ componentMap μ–΄λ”˜κ°€μ— λΉŒλ“œν•΄μ•Όν•˜κ³  κ·œμΉ™μ΄ μž¬κ·€ 적으둜 μ μš©λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

<InputField @type="text" /> λ˜λŠ” <InputField @type="checkbox" /> (예 <input> HTMLμ—μ„œ

input-field λŒ€ν•œ ν…œν”Œλ¦Ώμ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

{{#let (hash text=(component "inputs/text-field") checkbox=(component "inputs/checkbox")) as |components|}}
  {{component (get components @type)}}
{{/let}}

이런 μ‹μœΌλ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λ©΄ EmbroiderλŠ” λ²ˆλ“€μ— 두 개의 ꡬ성 μš”μ†Œ 만 ν¬ν•¨ν•˜λ©΄λœλ‹€λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒκ³Ό 같이 μž‘μ„± ν–ˆμŠ΅λ‹ˆκΉŒ?

{{component (concat "inputs/" <strong i="33">@type</strong> "-field")}}

(예, 그런 것듀은 λ†€λžκ²Œλ„ μΌλ°˜μ μž…λ‹ˆλ‹€)

EmbroiderλŠ” μ½”λ“œλ₯Ό μ‰½κ²Œ λΆ„μ„ν•˜κ³  λ²ˆλ“€μ— 포함될 ꡬ성 μš”μ†Œλ₯Ό μ œν•œ ν•  수 μ—†μŠ΅λ‹ˆλ‹€. 당신은 (λ˜ν•œ 맀우 μΌλ°˜μ μ΄λ‹€) μžλ°” μŠ€ν¬λ¦½νŠΈμ—μ„œ 일을 ν•œ κ²½μš°μ— 더 μ•…ν™”μž…λ‹ˆλ‹€ :

export default class extends Component {
  get innerComponent() {
    return `inputs/${this.args.type}-field`;
  }
}

이 ν…œν”Œλ¦ΏμœΌλ‘œ :

{{component this.innerComponent}}

μ•½κ°„μ˜ μ‘°μ •μ΄μ§€λ§Œ Embroiderκ°€ μ‹€μ œλ‘œ μ‚¬μš©λ˜λŠ” ꡬ성 μš”μ†Œλ₯Ό κ²°μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ λ‹€λ₯Έ 두 가지 κΈ°λ‚΄ κΈ°λŠ₯에 λŒ€ν•œ 연결을 더 μžμ„Ένžˆ μ„€λͺ…ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€.

  1. ν…œν”Œλ¦Ώ κ°€μ Έ 였기
  2. μ»΄ν¬λ„ŒνŠΈ 클래슀λ₯Ό 호좜 κ°€λŠ₯ ν•­λͺ©μœΌλ‘œ μ‚¬μš©

이 두 κΈ°λŠ₯을 μ‚¬μš©ν•˜μ—¬ 이전 예제λ₯Ό λ‹€μ‹œ μž‘μ„±ν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

---
import TextField from "./text-field";
import Checkbox from "./checkbox";
---
{{#let (hash text=TextField checkbox=Checkbox) as |components|}}
  {{component (get components @type)}}
{{/let}}

이것은 Embroiderκ°€ 이해해야 ν•  νŠΉλ³„ν•œ κ·œμΉ™μ„ μ œκ±°ν•˜κ³  λͺ¨λ“ˆμ— λŒ€ν•œ μ½”λ“œ λΆ„ν• μ„μœ„ν•œ μ‚¬μš©μž λͺ¨λΈμ„ λ§Œλ“œλŠ” 쒋은 속성을 가지고 μžˆμŠ΅λ‹ˆλ‹€.

μ»΄ν¬λ„ŒνŠΈ 클래슀λ₯Ό 호좜 κ°€λŠ₯ ν•­λͺ©μœΌλ‘œ μ‚¬μš©

RFC # 481 μ΄ν›„λ‘œ ꡬ성 μš”μ†Œ ν΄λž˜μŠ€λŠ” Glimmer VM이 ꡬ성 μš”μ†Œλ‘œ ν˜ΈμΆœν•˜λŠ” 데 ν•„μš”ν•œ λͺ¨λ“  정보λ₯Ό ν¬ν•¨ν•˜λŠ” μ™„μ „ν•œ λ…λ¦½λœ λ‹¨μœ„μ˜€μŠ΅λ‹ˆλ‹€.

μ°Έκ³  : μ΄λŠ” @ember/component λ˜λŠ” @glimmer/component μ—μ„œ 상속 된 ν΄λž˜μŠ€μ—λ§Œ ν•΄λ‹Ήλ˜λŠ” 것은 μ•„λ‹™λ‹ˆλ‹€. RFC 481 이후 Ember의 "ꡬ성 μš”μ†Œ"μ •μ˜λŠ” "ν…œν”Œλ¦Ώ 및 ꡬ성 μš”μ†Œ κ΄€λ¦¬μžμ™€ κ΄€λ ¨λœ 개체"이며 후크 ꡬ성 μš”μ†Œμ™€ 같은 μ‚¬μš©μž 지정 ꡬ성 μš”μ†Œλ₯Ό 포함

RFC # 432 (λ¬Έλ§₯ λ„μš°λ―Έ 및 μˆ˜μ • 자) 및 RFC # 496 (ν•Έλ“€ λ°” 엄격 λͺ¨λ“œ) 이후 Ember ν…œν”Œλ¦Ώ ꡬ문의 미래λ₯Όμœ„ν•œ μ„€κ³„λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. λ„μš°λ―Έ, ꡬ성 μš”μ†Œ λ˜λŠ” μˆ˜μ •μžλ₯Ό ν¬ν•¨ν•˜λŠ” ν‘œν˜„μ‹μ„ λ„μš°λ―Έ, ꡬ성 μš”μ†Œ λ˜λŠ” μˆ˜μ • 자둜 호좜 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

승인 된 RFCλŠ” ν˜„μž¬ μ»¬λ ‰μ…˜μ˜ μ˜λ―ΈλŠ”μ΄λ‹€ <SomeComponentClass /> (λ˜λŠ” <this.componentClass> 경우 this.componentClass ꡬ성 μš”μ†Œ 클래슀둜 확인) "단지 μž‘ν’ˆ"것. κ΅¬ν˜„ μž‘μ—…μ— λŒ€ν•œ 기둝 κ³„νšμ΄κΈ°λ„ν•©λ‹ˆλ‹€.

즉, λͺ…확성을 μœ„ν•΄μ΄ λ™μž‘μ„ λͺ…μ‹œ 적으둜 μ§€μ •ν•˜λŠ” μƒˆ RFCλ₯Ό λ§Œλ“€μ–΄μ•Όν•©λ‹ˆλ‹€.

HBSμ—μ„œ μœ νš¨ν•œ ꡬ성 μš”μ†Œ λͺ©λ‘μ„ μ–΄λ”˜κ°€μ— μ§€μ •ν•˜λŠ” 것은 κ°€λŠ₯ν•˜μ§€λ§Œ λ‹€μŒκ³Ό 같은 λͺ‡ κ°€μ§€μ£Όμ˜ 사항이 μžˆμŠ΅λ‹ˆλ‹€.

  1. ν˜„μž¬ μš°λ¦¬λŠ” @wycatsκ°€ μ§€μ ν•œ JS μ†”λ£¨μ…˜μ„ μ‚¬μš©ν•©λ‹ˆλ‹€. HBS κ³΅κΈ‰μžμ—μ„œ λ™μΌν•œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 것은 κ°€λŠ₯ν•˜μ§€λ§Œ 우리 λͺ¨λ‘κ°€ μ•Œκ³  μžˆλ“―μ΄ HBS의 λ…Όλ¦¬λŠ” 쑰금 더 μ–΄λ ΅μŠ΅λ‹ˆλ‹€. λ˜ν•œ κ³΅κΈ‰μž ꡬ성 μš”μ†Œκ°€ μ˜¬λ°”λ₯Έ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•˜λŠ” util ν•¨μˆ˜λ³΄λ‹€ μ˜¬λ°”λ₯Έ ꡬ성 μš”μ†Œλ₯Ό μ‚°μΆœν•˜λŠ”μ§€ λ‹¨μœ„ ν…ŒμŠ€νŠΈκ°€ 더 μ–΄λ ΅μŠ΅λ‹ˆλ‹€.
  2. 이것은 JS (μ–΄μ¨Œλ“  곡개 API 포함) afaikμ—λŠ” μ‘΄μž¬ν•˜μ§€ μ•Šμ§€λ§Œ μ—¬κΈ°μ„œλŠ” 디렉토리 ꡬ쑰λ₯Ό 이점으둜 μ‚¬μš©ν•˜λŠ” 것이 맀우 μ’‹μŠ΅λ‹ˆλ‹€. 예 :

    {{#let (lookup-directory "components/inputs/") as |components|}}
    {{/let}}
    

    이런 μ’…λ₯˜μ˜ 것은 디렉토리 κ΅¬μ‘°λ³„λ‘œ κ·Έλ£Ήν™” 된 λ‹€ν˜•μ„± μœ ν˜•μ„ μ•Œκ³  μžˆλ‹€λ©΄ μ‹œκ°„μ΄ 지남에 따라 μœ μ§€ 관리가 더 μ‰¬μ›Œ 질 수 μžˆμŠ΅λ‹ˆλ‹€.

μ–΄μ¨Œλ“  λ‚˜λŠ” 동적 ꡬ성 μš”μ†Œ 가이 문제λ₯Ό λŒ€μ‹ ν•˜κΈ°λ³΄λ‹€λŠ” λ…Όμ˜ν•˜κΈ° μœ„ν•΄ 자체 λ¬Έμ œκ°€ ν•„μš”ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€ πŸ™ˆ πŸ˜„

μ–΄μ¨Œλ“  λ‚˜λŠ” 동적 ꡬ성 μš”μ†Œ 가이 문제λ₯Ό λŒ€μ‹ ν•˜κΈ°λ³΄λ‹€λŠ” λ…Όμ˜ν•˜κΈ° μœ„ν•΄ 자체 λ¬Έμ œκ°€ ν•„μš”ν•˜λ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€ πŸ™ˆ πŸ˜„

λ™μ˜ν•˜λ©° RFC λ¦¬ν¬μ§€ν† λ¦¬μ—μ„œ 곧 ν•˜λ‚˜λ₯Ό μ—΄κ³  여기에 링크λ₯Ό κ²Œμ‹œν•©λ‹ˆλ‹€.

@mehulkar @wycats @jherdman μ‚¬μš©μžκ°€ λ™μ μœΌλ‘œ 호좜 κ°€λŠ₯ν•œ ꡬ성 μš”μ†Œ λͺ©λ‘μ„ κ°€μ Έμ˜¬ 수 μžˆλ„λ‘ ν—ˆμš©ν•˜λŠ” 것은 μ–΄λ–»μŠ΅λ‹ˆκΉŒ? μΆ”κ°€ μˆ˜μ€€μ˜ κ°„μ ‘ μ°Έμ‘°λ₯Ό ν¬ν•¨ν•˜λŠ” λ„μš°λ―Έλ³΄λ‹€ 따라 κ°€κΈ°κ°€ 훨씬 μ‰½μŠ΅λ‹ˆλ‹€.

import Component1 from './dynamic/component-1';
import Component2 from './dynamic/component-2';
import Component3 from './dynamic/component-3';

export default class extends Component {
  get innerComponent() {
    switch(this.args.type) {
      case 'one':
        return Component1;
      case 'two':
        return Component2;
      case 'three':
        return Component3;
      default:
        // handle invalid type
    }
  }
}

그런 λ‹€μŒ ν…œν”Œλ¦Ώμ€ {{#let (component this.innerComponent) as |DynamicComponent|}} λ˜λŠ” 이와 μœ μ‚¬ν•œ μž‘μ—…μ„ μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

더 μ‰½κ²Œ 검색 / 읽기 / λΆ„μ„ν•˜κ³  μ΄λŸ¬ν•œ ꡬ성 μš”μ†Œκ°€ μ‚¬μš©λ˜λŠ” μœ„μΉ˜λ₯Ό μ‰½κ²Œ κ°μ§€ν•˜λŠ” 이와 같은 것을 μ„ ν˜Έν•©λ‹ˆλ‹€. 생각?

@ Samsinite λ„€, 그게 아이디어라고 μƒκ°ν•©λ‹ˆλ‹€. HBS의 λ„μš°λ―ΈλŠ” λŒ€λΆ€λΆ„ ꡬ문 섀탕이며 ν…œν”Œλ¦Ώ μ „μš© ꡬ성 μš”μ†Œμ— μœ μš©ν•©λ‹ˆλ‹€.

@Samsinite λŠ” 기본적으둜 단기 μˆ˜μ •μœΌλ‘œ μ œμ•ˆν•œ κ²ƒμž…λ‹ˆλ‹€ (ν…œν”Œλ¦Ώ κ°€μ Έ 였기 μ „).

μ»΄ν¬λ„ŒνŠΈ 클래슀 κ°€ 호좜 κ°€λŠ₯ν•˜λ„λ‘ ν—ˆμš©ν•΄μ•Όν•˜λŠ”λ°, 이것이 μ œκ°€μ΄ 주석 μ—μ„œ 이야기 ν•œ κ²ƒμž…λ‹ˆλ‹€.

κ°€μž!

μ•„, ν…œν”Œλ¦Ώ μ „μš© ꡬ성 μš”μ†Œμ—λŠ” μ˜λ―Έκ°€ μžˆμŠ΅λ‹ˆλ‹€. μ˜€ν•΄ν•΄μ„œ μ£„μ†‘ν•©λ‹ˆλ‹€. :). λ˜ν•œ λ‹€μŒμ˜ ν…œν”Œλ¦Ώ μ „μš© ꡬ성 μš”μ†Œμ— λŒ€ν•œ ꡬ문을 μ’‹μ•„ν•©λ‹ˆλ‹€.

---
import TextField from "./text-field";
import Checkbox from "./checkbox";
---
{{#let (hash text=TextField checkbox=Checkbox) as |components|}}
  {{component (get components @type)}}
{{/let}}

사싀, λ‚˜λŠ” νŒ€μ˜ λ‹€λ₯Έ μ‚¬λžŒλ“€μ΄ 더 μ‰½κ²Œ 읽을 수 μžˆλ‹€κ³  μƒκ°ν•˜λŠ” 것에 따라 ν…œν”Œλ¦Ώκ³Ό js 지원 ꡬ성 μš”μ†Œμ—λ§Œ μ‚¬μš©ν•  κ²ƒμž…λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰