์ด ํ์คํธ ๋ฌธ์ ๋ Ember.js์์ Glimmer ๊ตฌ์ฑ ์์์ ๊ตฌํ์ ์ถ์ ํฉ๋๋ค.
Glimmer.js ๊ตฌ์ฑ ์์์๋ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.
tagName
, attributeBindings
๋ฑ ์์){{@firstName}}
์ ๊ฐ์ด @
์ ๋์ฌ์
๋๋ค.this.args
๋ก ์ค์ ๋์์ต๋๋ค.@tracked
์์ฑ์ผ๋ก ์ฃผ์ ์ฒ๋ฆฌ๋ฉ๋๋ค.<AngleBracket />
๊ตฌ๋ฌธ์ ํตํด ํธ์ถ๋ฉ๋๋ค.โฆattributes
๋ฅผ ํตํด ์์ฑ์ "์คํ๋ํ
"ํ ์ ์์ต๋๋ค.Ember์ ์ฆ๋ถ์ฃผ์ ์ ์ ์ ๋ฐ๋ผ ์ฐ๋ฆฌ๋ ์ด ๊ธฐ๋ฅ์ ์ ๋์จ์ ํตํด ํ๋์ฉ ๋์ ํ๊ณ ์ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ปค๋ฎค๋ํฐ๋ ํ๋ก์ธ์ค ์ด๊ธฐ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ณ ํผ๋๋ฐฑ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
์ฌ์ค, ์ฐ๋ฆฌ๋ ์ด๋ฏธ Ember์์ Glimmer ๊ตฌ์ฑ ์์๋ก ๊ฐ๋ ๊ธธ์ ์์ํ์ต๋๋ค. ์ฒ์ ๋ ๊ธฐ๋ฅ์ ์ด๋ฏธ ์ฐฉ๋ฅํ๊ธฐ ์์ํ์ต๋๋ค.
template-only-glimmer-components
์ ํ์ ๊ธฐ๋ฅ ์ด ํ์ฑํ๋์๋ค๊ณ ๊ฐ์ ).@
์ ๋์ฌ(์: {{@firstName}}
)๋ฅผ ํตํด ํ
ํ๋ฆฟ์์ ์ธ์์ ์ก์ธ์คํ ์ ์์ต๋๋ค.์ด๋ฒ ํธ์์๋ ์ ๋์จ์ด ๋์ฒด ๊ตฌ์ฑ ์์ ๊ตฌํ์ ์ ๊ณตํ๋๋ก ํ์ฉํ ๋ค์ @glimmer/component
ํจํค์ง๋ฅผ Glimmer.js ๊ตฌ์ฑ ์์ API๋ฅผ ๊ตฌํํ๋ Ember ์ ๋์จ์ผ๋ก ๋ณํํ์ฌ Glimmer ๊ตฌ์ฑ ์์๋ฅผ Ember๋ก ๊ฐ์ ธ์ค๋ ํ๋ก์ธ์ค๋ฅผ ์๋ฃํ๋ ๊ฒ์ ์ ์ํฉ๋๋ค.
์ฐ๋ฆฌ๋ ๊ทธ ์์ ์ ๋จ๊ณ๋ก ๋๋ ๊ฒ์ด๋ฉฐ, ๊ฐ๊ฐ์ ๊ธฐ์กด Ember ์ฑ๊ณผ ์ ๋์จ์ ์ด์ ์ ์ ๊ธ ํด์ ํฉ๋๋ค. 0๋จ๊ณ๋ ๋์ฒด ๊ตฌ์ฑ ์์ ๊ตฌํ์ ์ง์ํ๊ธฐ ์ํด Ember.js์ ํ์ํ ๊ธฐ๋ณธ ์์๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๋๋ค. 1, 2, 3๋จ๊ณ๋ Glimmer.js ๊ตฌ์ฑ ์์ API๋ฅผ ์ ์ง์ ์ผ๋ก ํ์ฑํํ๋ ๊ฒ์ ๋๋ค.
0๋จ๊ณ์ 1๋จ๊ณ์ ๋ํด ์์ธํ ์ดํด๋ณด๋ ๋์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ๊ฐ ์๋ฃ์ ๊ฐ๊น์์ง ๋๊น์ง ์ดํ ๋จ๊ณ์ ๊ธฐ์ ์ ์ธ ์ธ๋ถ ์ ๋ณด ํ์์ ์ฐ๊ธฐํ ๊ฒ์ ๋๋ค.
TL;DR: Ember.js์ CustomComponentManager API๋ฅผ ์ถ๊ฐํ์ฌ ์ ๋์จ์ด ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ API๋ฅผ ๊ตฌํํ ์ ์๋๋ก ํฉ๋๋ค.
ํ์ฌ Ember ์ฑ์ ๋ชจ๋ ๊ตฌ์ฑ ์์๋ Ember.Component
ํ์ ํด๋์ค๋ก ๊ฐ์ฃผ๋ฉ๋๋ค. Ember์์ ๋์ฒด ๊ตฌ์ฑ ์์ API๋ฅผ ์ง์ํ๋ ค๋ฉด ๊ตฌ์ฑ ์์ ๋์์ด ์ธ์ ์ด๋ป๊ฒ ๋ณ๊ฒฝ๋์ด์ผ ํ๋์ง Ember์ ์๋ฆฌ๋ ๋ฐฉ๋ฒ์ด ํ์ํฉ๋๋ค.
"์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๋์"์ด๋ผ๊ณ ํ ๋ ๊ตฌ์ฒด์ ์ผ๋ก ๋ค์์ ์๋ฏธํฉ๋๋ค.
Glimmer VM์ ์ด๋ฌํ ๊ฒฐ์ ์ ๋ด๋ฆฌ๋ ๊ฐ์ฒด์ธ "๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์"์ ๊ฐ๋ ์ ๋์ ํ์ง๋ง ์ด API๋ ๋งค์ฐ ๋ฎ์ ์์ค์ ๋๋ค. ์์ฑํ๊ธฐ ์ด๋ ต๊ณ ๋ค๋ฅธ ๊ตฌ์ฑ ์์๋ฅผ ์์์ํค๋ ๋ฐฉ์์ผ๋ก ์์ฑํ๊ธฐ ์ฝ๊ณ ์์ง ์์ ์ ์ด์ง ์๊ธฐ ๋๋ฌธ์ Ember์์ ๊ณต๊ฐ API๋ก ์ง์ ์ฑํํ๋ ๊ฒ์ ์๊ธฐ์์กฐ์ ๋๋ค.
๋์ ์ ๋๋ฆฌ์ ํจํด์ ๊ตฌํํ๋ CustomComponentManager
๋ผ๋ ์๋ก์ด Ember API๋ฅผ ์ ์ํฉ๋๋ค. CustomComponentManager
๋ ์์ ํ ComponentManager
Glimmer VM API๋ณด๋ค ๋ ์์ API ๋
ธ์ถ ์์ญ์ ์ ๊ณตํ๋ฏ๋ก ์ ๋์จ ์์ฑ์๊ฐ "์ฑ๊ณต์ ๊ตฌ๋ฉ์ด"์ ๋น ์ง ์ ์์ต๋๋ค.
๊ทธ๋ ๋ค๋ฉด Ember๋ ์ฃผ์ด์ง ๊ตฌ์ฑ ์์์ ์ฌ์ฉํ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ์ด๋ป๊ฒ ์ ์ ์์ต๋๊น? Custom Components RFC ์ ์๋ ๋ฐ๋ณต์์๋ Ember์ ์ด์ฌํ ๋ฑ๋กํ๊ณ ์ฌ์ฉํ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ์ง์ ํ๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ธ ComponentDefinition
๊ฐ๋
์ ๋์
ํ์ต๋๋ค.
ComponentDefinition
์ ๊ทผ ๋ฐฉ์์ ์ฃผ์ ์ด์ ์ค ํ๋๋ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์ ํ์ธ์ด ๋น๋ ์ ๋ฐ์ํ ์ ์๋ค๋ ๊ฒ์
๋๋ค. ๋ถํํ๋ ์ด๋ ์ ํํ ์ด๋ป๊ฒ ๋ฑ๋ก๋๋์ง์ ๋ํ API๋ฅผ ์ค๊ณํด์ผ ํ๋ฉฐ ๋น๋ ํ์ดํ๋ผ์ธ๊ณผ์ ์ผ์ข
์ ํตํฉ์ ์๋ฏธํ ์ ์์ต๋๋ค.
๋์ ์ปดํฌ๋ํธ ํด๋์ค์ ์ฃผ์์ ํตํด ๋ฐํ์์ ์ปดํฌ๋ํธ์ ๊ด๋ฆฌ์๋ฅผ ์ค์ ํ๊ธฐ ์ํ API๋ฅผ ์ ์ํฉ๋๋ค. ์ด ์ฆ๋ถ ๋จ๊ณ๋ฅผ ํตํด ์ฅ๊ธฐ์ ์ธ ์๋ฃจ์ ์ด ์ค๊ณ๋๋ ๋์ ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์์ ๋ํ ์์ ์ ๊ณ์ํ ์ ์์ต๋๋ค.
์ด ๋ฐ๋ณต์์ ๊ตฌ์ฑ ์์๋ ๋ช
์์ ์ผ๋ก ๋์ฒด ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ์ ํํด์ผ ํฉ๋๋ค. Ember์์ ๋ด๋ณด๋ธ ํน์ componentManager
ํจ์๋ฅผ ํตํด ์ด ์์
์ ์ํํฉ๋๋ค. ์ด ํจ์๋ ๋ฐํ์ ์ ํน์ ๊ตฌ์ฑ ์์ ํด๋์ค์ ์ฌ์ฉํด์ผ ํ๋ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์์ ์ฃผ์์ ์ถ๊ฐํฉ๋๋ค.
import { componentManager } from '@ember/custom-component-manager';
import EmberObject from '@ember/object';
export default componentManager(EmberObject.extend({
// ...
}), 'glimmer');
๊ฒฐ๊ตญ ์ด๊ฒ์ ํด๋์ค ๋ฐ์ฝ๋ ์ดํฐ๊ฐ ๋ ์ ์์ต๋๋ค.
import { componentManager } from '@ember/custom-component-manager';
export default @componentManager('glimmer') class {
// ...
}
์ด ๊ตฌ์ฑ ์์๊ฐ ์ฒ์ ํธ์ถ๋ ๋ Ember๋ ํด๋์ค๋ฅผ ๊ฒ์ฌํ์ฌ ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์ ์ฃผ์์ด ์๋์ง ํ์ธํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ๋ฌธ์์ด ๊ฐ์ ์ฌ์ฉํ์ฌ ์ปจํ
์ด๋์ ๋ํ ์กฐํ๋ฅผ ์ํํฉ๋๋ค. ์์ ์์์ Ember๋ ์ปจํ
์ด๋ ํค๊ฐ component-manager:glimmer
๊ฐ์ฒด์ ๋ํด ์ปจํ
์ด๋์ ์์ฒญํฉ๋๋ค.
๋ฐ๋ผ์ ์ ๋์จ์ ์ผ๋ฐ ํด์๋ ์๋ฏธ ์ฒด๊ณ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ฐ๋ฆฌ์ Glimmer ๊ตฌ์ฑ ์์ ์ ๋์จ์ addon/component-managers/glimmer.js
์์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ๋ด๋ณด๋ผ ์ ์์ผ๋ฉฐ ์ด๋ ์ผ๋ฐ ํด๊ฒฐ ๊ท์น์ ํตํด ์๋์ผ๋ก ๊ฒ์๋ฉ๋๋ค.
์ด API๋ ์ฅํฉํ๊ณ ํน๋ณํ ์ธ์ฒด๊ณตํ์ ์ด์ง ์์ง๋ง ์ฑ๊ณผ ์ ๋์จ์ ์ฃผ์์ด ์๋ ์์ฒด ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ๋์
ํ์ฌ ์ด๋ฅผ ์ถ์ํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด turbo-component
๋ผ๋ ์ ๋์จ์ด ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ์ ๊ณตํ๋ ค๋ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ด ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ๋ด๋ณด๋ผ ์ ์์ต๋๋ค.
// addon/index.js
import EmberObject from '@ember/object';
import { componentManager } from '@ember/custom-component-manager';
export default componentManager(EmberObject.extend({
// ...
}), 'turbo');
์ด ์ ๋์จ์ ์ฌ์ฉ์๋ TurboComponent
๊ธฐ๋ณธ ํด๋์ค๋ฅผ ํ์ ํด๋์ค๋ก ์ง์ ํ์ฌ ์ฌ๋ฐ๋ฅธ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ์ฌ์ฉํ๋ ๊ตฌ์ฑ ์์๋ฅผ ์ ์ํ ์ ์์ต๋๋ค.
import TurboComponent from 'turbo-component';
export default TurboComponent.extend({
didInsertElementQuickly() {
// ...
}
});
์ด๋ค ๊ตฌ์ฑ ์์๋ ์ฌ์ด ์๋๋ฉฐ ํ์ ํธํ์ฑ์ ์ํด ์ ๊ตฌ์ฑ ์์ API์ ๋์ ์ผ๋ก ์ธํด ๊ธฐ์กด ๊ตฌ์ฑ ์์๊ฐ ์์๋์ง ์๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
์ด์ ๋ํ ํ ๊ฐ์ง ์๋ ๊ธฐ์กด ๋ณด๊ธฐ ๊ณ์ธต ๊ตฌ์กฐ API์
๋๋ค. Ember ๊ตฌ์ฑ ์์๋ parentView
์์ฑ์ ํตํด ์์ ๊ตฌ์ฑ ์์๋ฅผ ๊ฒ์ฌํ ์ ์์ต๋๋ค. ๋ถ๋ชจ๊ฐ Ember.Component
๊ฐ ์๋๋๋ผ๋ ์์ Ember ๊ตฌ์ฑ ์์์๋ ์ฌ์ ํ null์ด ์๋ parentView
์์ฑ์ด ์์ด์ผ ํฉ๋๋ค.
ํ์ฌ Ember์ CurlyComponentManager
๋ ์ด ์ํ๋ฟ๋ง ์๋๋ผ ์์
๋์๊ณผ ๊ฐ์ ๋ค๋ฅธ ์ฃผ๋ณ "๋ฒ์ ์ํ"๋ฅผ ์ ์ง ๊ด๋ฆฌํ๋ ์ญํ ์ ํฉ๋๋ค.
์ ๋๋ก ๊ตฌํ๋์ง ์์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๊ฐ ๊ธฐ์กด ์์คํ ์ ๋ถ๋ณ์ฑ์ ์๋ฐํ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๊ตฌ์ฑ ํจํด์ ์ฌ์ฉํ์ฌ ๊ธฐ๋ณธ API์ ๋ ์นด๋ก์ด ๋ชจ์๋ฆฌ๋ฅผ ์จ๊ธฐ๋ฉด์ ๋์์ ์ฌ์ฉ์ ์ง์ ํฉ๋๋ค.
import CustomComponentManager from "@ember/custom-component-manager";
export default new CustomComponentManager({
// major and minor Ember version this manager targets
version: "3.1",
create({ ComponentClass, args }) {
// Responsible for instantiating the component class and passing provided
// component arguments.
// The value returned here is passed as `component` in the below hooks.
},
getContext(component) {
// Returns the object that serves as the root scope of the component template.
// Most implementations should return `component`, so the component's properties
// are looked up in curly expressions.
},
update(component, args) {
// Called whenever the arguments to a component change.
},
destroy(component) {
}
});
Ember์ Component
๊ธฐ๋ณธ ํด๋์ค๋ ๋ ์ด์ ๋ง์ด ์ฌ์ฉ๋์ง ์๋ ๊ธด ๊ธฐ๋ฅ ๋ชฉ๋ก์ ์ง์ํฉ๋๋ค. ์ด๋ฌํ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ์๋ ๊ฒฝ์ฐ์๋ ์ฑ๋ฅ ๋น์ฉ์ ๋ถ๊ณผํ ์ ์์ต๋๋ค.
์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ก @glimmer/component
ํจํค์ง๋ฅผ ํตํด ๊ฐ์ํ๋ Glimmer.js ๊ตฌ์ฑ ์์ API๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๊ณ ์ ํฉ๋๋ค. ๋ง์ด๊ทธ๋ ์ด์
์ ์ฝ๊ฒํ๊ธฐ ์ํด, ์ฐ๋ฆฌ๋ ํฌ๋ฏธํ ๋น์ ๊ตฌํ์ ์ ๊ณต ํ ๊ฒ์
๋๋ค Component
๊ธฐ๋ณธ ํด๋์ค์๋ ์์ Ember.Object
์์ @glimmer/component/compat
.
๋ค์์ "Ember-Glimmer ๊ตฌ์ฑ ์์"๊ฐ ์ด๋ป๊ฒ ๋ณด์ด๋์ง์ ๋ํ ์์ ๋๋ค.
// src/ui/components/user-profile/component.js
import Component from '@glimmer/component/compat';
import { computed } from '@ember/object';
export default Component({
fullName: computed('args.firstName', 'args.lastName', function() {
let { firstName, lastName } = this.args
return `${firstName} ${lastName}`;
})
isAdmin: false,
toggleAdmin() {
this.set('isAdmin', !this.isAdmin);
}
});
{{!-- src/ui/components/user-profile/template.hbs --}}
<h1>{{fullName}}</h1>
<p>
Welcome back, {{@firstName}}!
{{#if isAdmin}}
<strong>You are an admin.</strong>
{{/if}}
</p>
<button {{action toggleAdmin}}>Toggle Admin Status</button>
์ด๋ฌํ ๊ตฌ์ฑ ์์์ ์ฃผ๋ชฉํ ๋งํ ํน์ฑ:
actions
ํด์์ ์ค์ฒฉ๋ ํ์๊ฐ ์์ต๋๋ค.args
์์ฑ์ ์ธ์๊ฐ ์ค์ ๋ฉ๋๋ค.ํฌํจ ๋์ง ์์ ํญ๋ชฉ ๋ ์ค์ํฉ๋๋ค.
@tracked
์์ฑ์ 3๋จ๊ณ๊น์ง ์ง์๋์ง ์์ต๋๋ค.layout
๋๋ template
์์ฑ์ด ์์ต๋๋ค.childViews
, parentView
, nearestWithProperty
๋ฑ๊ณผ ๊ฐ์ ๋ทฐ ๊ณ์ธต ๊ตฌ์กฐ์ ๊ด๋ จ๋ ๋ฉ์๋ ๋๋ ์์ฑ์ด ์์ต๋๋ค.tagName
, attributeBindings
๋๋ ๊ธฐํ ์ฌ์ฉ์ ์ ์ JavaScript DSL์ด ์์ต๋๋ค.send
๋๋ sendAction
๊ฐ ์์ต๋๋ค.ember-view
ํด๋์ค ๋๋ ์๋ ์์ฑ๋ guid ์์ ID๊ฐ ์์ต๋๋ค.rerender()
๋ฐฉ๋ฒ์ด ์์ต๋๋ค.attrs
์์ฑ์ด ์์ต๋๋ค(๋์ args
์ฌ์ฉ).this.$()
๊ฐ ์์ต๋๋ค.appendTo
๊ตฌ์ฑ ์์๊ฐ ์์ต๋๋ค.willInsertElement
didRender
willRender
willClearRender
willUpdate
didReceiveAttrs
didUpdateAttrs
parentViewDidChange
on()
์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์์ต๋๋ค. ํํฌ๋ ๋ฉ์๋๋ก ๊ตฌํํด์ผ ํฉ๋๋ค.์ด ๊ธฐ๋ฅ ์ธํธ์ ํฅ๋ฏธ๋ก์ด ๋ถ์์ฉ ์ค ํ๋๋ JavaScript ํด๋์ค ๋ฅผ ES Classes RFC ์์ ์ ์๋ ์ค๊ณ์ ํจ๊ป ์ ๊ตฌ์ฑ ์์์ ๋์ฒด ๊ตฌํ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
// src/ui/components/user-profile/component.js
import Component from '@glimmer/component/compat';
import { computed } from 'ember-decorators/object';
export default class extends Component {
isAdmin = false;
@computed('args.firstName', 'args.lastName')
get fullName() {
let { firstName, lastName } = this.args;
return `${firstName} ${lastName}`;
})
toggleAdmin() {
this.set('isAdmin', !this.isAdmin);
}
});
2 ๋จ๊ณ (๊ฐ๊ดํธ ํตํด ์ปดํฌ๋ํธ๋ฅผ ํธ์ถ ๊ฐ๋ฅ <UserAvatar @user={{currentUser}} />
(์ค๊ดํธ ์ด์ธ์) {{my-component user=currentUser}}
). ์ด ๊ตฌ๋ฌธ์ ๊ตฌ์ฑ ์์ ์ธ์์ HTML ์์ฑ์ ๋ช
ํํ๊ฒ ๊ตฌ๋ถํ๊ธฐ ๋๋ฌธ์ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ฉด โฆattributes
๋ฅผ ํตํด ์์ฑ์ ๊ตฌ์ฑ ์์ ํ
ํ๋ฆฟ์ "๋ถํ "ํ ์๋ ์์ต๋๋ค.
{{! src/ui/components/UserAvatar/template.hbs }}
<div ...attributes> {{! <-- attributes will be inserted here }}
<h1>Hello, {{@firstName}}!</h1>
</div>
<UserAvatar @user={{currentUser}} aria-expanded={{isExpanded}} />
๊ทธ๋ฌ๋ฉด ๋ค์๊ณผ ์ ์ฌํ ์ถ๋ ฅ์ด ๋ ๋๋ง๋ฉ๋๋ค.
<div aria-expanded="true">
<h1>Hello, Steven!</h1>
</div>
3๋จ๊ณ์์๋ Ember์ @tracked
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด ์ถ์ ๋ ์์ฑ์ ํ์ฑํํฉ๋๋ค. Ember์ ๊ฐ์ฒด ๋ชจ๋ธ๊ณผ ์ถ์ ๋ ์์ฑ ๊ฐ์ ์ํธ ์ด์ฉ์ฑ์ ๋ํ ์ธ๋ถ ์ฌํญ์ ์์
์ค์
๋๋ค. ์ถ์ ๋ ์์ฑ์ด ํ์๋๋ฉด ์ฌ์ฉ์๋ @glimmer/component/compat
๋ชจ๋์ ์ญ์ ํ๊ณ Ember.Object๊ฐ ์๋ ์ผ๋ฐ ๊ตฌ์ฑ ์์ ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ต๊ทผ์ ๋ณํฉ๋ "์๋ ์ถ์ " ๊ธฐ๋ฅ(๊ณ์ฐ๋ ์์ฑ ์ข ์์ฑ์ ์๋์ผ๋ก ์ถ๋ก )๊ณผ ํจ๊ป ์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ฝ๋๋ฅผ ๋์ฑ ๋จ์ํํ๋ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
import Component, { tracked } from '@glimmer/component';
export default class extends Component {
<strong i="24">@tracked</strong> isAdmin = false;
<strong i="25">@tracked</strong> get fullName() {
let { firstName, lastName } = this.args;
return `${firstName} ${lastName}`;
}
toggleAdmin() {
this.isAdmin = !this.isAdmin;
}
}
๊ธฐ์กด CSS์์ ํธํ์ฑ์ ์ํด ember-view
ํด๋์ค ์ด๋ฆ ๋๋ ์๋ ์์ฑ๋ id
์์ฑ๊ณผ ๊ฐ์ ํญ๋ชฉ์ Glimmer ๊ตฌ์ฑ ์์์ ๋ค์ ์ถ๊ฐํ ์ ์์ต๋๊น?
์. ์์:
<div class="ember-view" id="{{uniqueId}}">
Component content goes here.
</div>
import Component from '@glimmer/component';
import { guidFor } from '@ember/object/internals';
export default class extends Component {
get uniqueId() {
return guidFor(this);
}
}
custom-component-manager
์ง์ CustomComponentManager
๊ตฌํ์ด ์๋ Ember.js์ ์งํ ์ค์ธ ๋ถ๊ธฐtracked
์ง์ @tracked
์์ฑ๊ณผ Ember ๊ฐ์ฒด ๊ฐ์ ์ํธ ์ด์ฉ์ฑ์ ๋ํ ์์
์ด ์๋ Ember.js์ ์งํ ์ค์ธ ๋ถ๊ธฐ์๋ ๋ชฉ๋ก์ ์ฌ์ฉํ์ฌ ์งํ ์ค์ธ ์์ ์ ์ถ์ ํฉ๋๋ค. ๊ตฌํํ๋ ๋์ ๋ ๋ง์ด ๋ฐฐ์ฐ๋ฉด ๋ชฉ๋ก์ ํญ๋ชฉ์ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํฉ๋๋ค.
glimmer-custom-component-manager
๊ธฐ๋ฅ ํ๋๊ทธ ์ถ๊ฐcomponentManager
๊ธฐ๋ฅ ๊ตฌํ{ componentManager } from '@ember/custom-component-manager'
๋ก ๋
ธ์ถCustomComponentManager
API ๊ตฌํCustomComponentManagerDelegate
์ธํฐํ์ด์ค ์ ์version
create()
getContext()
update()
destroy?()
didCreate?()
didUpdate?()
getView?()
version
์์ฑ ํ์ธchildViews
๋ฐ parentView
sparkles-components
์ ๋์จ ์ฌ์ฉ ์ง์componentManager
์ฃผ์์ ๊ฐ์ ธ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.CustomComponentManager
๊ตฌํ์ Ember์ ์ปจํ
์ด๋๋ฅผ ํตํด ๊ฒ์ ๊ฐ๋ฅํด์ผ ํฉ๋๋ค.@glimmer/component
๋ฅผ Ember ์ ๋์จ์ผ๋ก ์ฌ์ฉ ์ง์import Component from '@glimmer/component'
๋ ์ผ๋ฐ JavaScript ๊ธฐ๋ณธ ํด๋์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.import Component from '@glimmer/component/compat'
๋ Ember.Object
๊ธฐ๋ณธ ํด๋์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.create(injections)
didInsertElement()
willDestroy()
didUpdate()
click()
๋ฑ)๋ ํธ๋ฆฌ๊ฑฐ ๋์ง ์์์ผ ํฉ๋๋ค.this.bounds
this.element
๊ณ์ฐ๋ ์์ฑ ๋ณ์นญ์ this.bounds
this.args
๋ ์์ฑ์์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.this.args
didUpdate
๊ฐ ํธ์ถ๋๊ธฐ ์ ์ this.args
๊ฐ ์
๋ฐ์ดํธ๋ฉ๋๋ค.this.args
๋ ๋ฌดํ ์ฌ๋ ๋๋ง ์ฃผ๊ธฐ๋ฅผ ํธ๋ฆฌ๊ฑฐํด์๋ ์ ๋ฉ๋๋ค(ํ์ธ ํ์).args
์ ์์กดํ๋ ๋ฐฉ๋ฒcreate()
๋ฉ์๋๊ฐ ์๋ ํด๋์ค)๋ฅผ ๊ตฌ์ฑ ์์ ํด๋์ค๋ก ์ด๋ป๊ฒ ์ฌ์ฉํฉ๋๊น? ๊ตฌ์ฑ ์์๋ฅผ ์ด๊ธฐํํ๋ ํ๋กํ ์ฝ์ ๊ฐ๋จํด ๋ณด์ด์ง๋ง ์์ธ๋ก ๊น๋ค๋กญ์ต๋๋ค.CustomComponentManager
์ ๊ฐ์ "์ ๋์จ API"๋ฅผ ๋ฌธ์ํํ๊ธฐ์ ๊ฐ์ฅ ์ข์ ์์น๋ ์ด๋์
๋๊น?CustomComponentManager
๋ฒ์ ๊ด๋ฆฌ๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํฉ๋๊น?๋์์ด ํ์ํ์๋ฉด Ember ์ปค๋ฎค๋ํฐ Slack ์ #st-glimmer-components ์ฑ๋์์ ์์ ์ ์กฐ์ ํ๊ฒ ์ต๋๋ค! ์์์ง๊ฐ ์ด๋ป๊ฒ ๋ง๋ค์ด์ง๋์ง ๊ถ๊ธํ๋ค๋ฉด Lurkers๋ ํ์ํฉ๋๋ค.
์ด๊ฒ์ ๊ณ ๋ คํ๋ฉด;
{{! src/ui/components/UserAvatar/template.hbs }}
<div ...attributes> {{! <-- attributes will be inserted here }}
<h1>Hello, {{@firstName}}!</h1>
</div>
์ ์ค๊ดํธ๊ฐ ๋์ ๋ณ์( {{@firstName}}
)๋ฅผ ๋ํ๋ด๋ ๋ฐ ์ฌ์ฉ๋์ง๋ง splatted ์์ฑ์ ํ์๋์ง ์๋์ง ์ดํด๊ฐ ๋์ง ์์ต๋๊น? ์๊ฐ์ ์ผ๋ก๋ <div ...attributes>
๊ฐ ๋ ๋๋ง๋ ๊ฒ์ผ๋ก ๋ณด์
๋๋ค. ์ผ๊ด์ฑ์ ์ํด <div {{...attributes}}>
๋ก ๋ ๋ซ์ง ์์๊น์?
์ด๋ป๊ฒ ๋ณด์ด๊ณ ์๋ํด์ผ ํ๋์ง ๋ ผ์ํ ์ ์๋ glimmer ๊ตฌ์ฑ ์์์ ๋ํ RFC๊ฐ ์์ต๋๊น?
@tomdale ์์ ๋ฌธ์ ๋ ๊ตฌ์ฑ ์์ ํธํ ๋ชจ๋ ๋ฌธ์ํ๋ฅผ ์ธ๊ธํ์ง๋ง ๋ง์ด๊ทธ๋ ์ด์
๊ฐ์ด๋ ๋ฌธ์ํ๋ ์ธ๊ธํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์๋ฅผ ๋ค์ด didReceiveAttrs()
๊ฐ ๋ ์ด์ ์กด์ฌํ์ง ์๋๋ค๋ ์ฌ์ค์ ์๋นํ ๋๋๊ณ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์๋ก์ด ๋ชจ๋ฒ ์ฌ๋ก ํจํด์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ๋ฌธ์๊ฐ ์์ผ๋ฉด ์ข์ ๊ฒ์
๋๋ค.
@dbbk ์ฐ๋ฆฌ๊ฐ {{...attributes}}
ํ์๋ก ํ์ง ์๋ ๊ฐ์ฅ ํฐ ์ด์ ๋ ์ฐ๋ฆฌ๊ฐ curlies๋ฅผ ํ์๋ก ํ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ์ ๊ฐ์ด ์ผ๋ฐ ์์ฑ๊ณผ ๊ตฌ๋ฌธ์ ์ผ๋ก ๋ชจํธํ์ง ์๊ณ 4๊ฐ์ ์ ์ ๋ฌธ์๊ฐ ํ์ดํํ๊ธฐ ์ฝ๊ณ ์๊ฐ์ ์ผ๋ก ๋ ์๋๋ฝ๊ฒ ๋ณด์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
๋ํ ์ฌ๋๋ค์ด attributes
๊ฐ ๋ฒ์ ๋ด ์์ฑ์ด๋ผ๊ณ ๊ฐ์ ํ ์ ์๋ค๊ณ ์๊ฐํ์ง๋ง ๊ทธ๋ ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํด๋น ๊ตฌ๋ฌธ์์ ์ ์ํ๋ ๊ฒ์ฒ๋ผ <SomeComponent something={{attributes}} />
์ํํ ์๋ ์์ต๋๋ค. ๋ํ ์คํ๋ ๋ ๊ตฌ๋ฌธ์ด ์๋ํ์ง ์์ ๋ ๋ค๋ฅธ ์์น์์ ์๋ํ๋ค๋ ๊ฒ์ ๋ ๊ฐ๋ ฅํ๊ฒ ์์ํฉ๋๋ค.
@arguments
๋ฅผ ๋ชจ๋ ํน์ ํ
ํ๋ฆฟ ๋ฐ์ธ๋ฉ์ผ๋ก ์ฑํํ๊ณ ํธ๋ค๋ฐ์ ...
์คํ๋ ๋ ๊ตฌ๋ฌธ์ ์ถ๊ฐํ์๋ ์ ์์ด ์์์ง๋ง ์ฆ๊ฐ์ ์ธ ๋ก๋๋งต์ ์๋ ์ค๊ณ ๋ฐ ๊ตฌํ์ด ํ์ํฉ๋๋ค. ๋ฏธ๋์ ...attributes
๋ฅผ {{...@attributes}}
๋๋ ์ด์ ์ ์ฌํ ๊ฒ์ผ๋ก ๋ฐ๊พธ๋ฉด ์ ํ ๋๋ผ์ง ์์ ๊ฒ์
๋๋ค.
@Gaurav0 Glimmer ๊ตฌ์ฑ ์์ API๋ Ember ์ฑ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋๊ธฐ ์ ์ RFC ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์น๊ฒ ๋ฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์ ์ ๊ทผ ๋ฐฉ์์ ํ ๊ฐ์ง ์ข์ ์ ์ "์ฐจ์ธ๋" API๋ฅผ ์ ์ํํ์ง ์์ง๋ง ์ ๋์จ ์์ฝ์์คํ ์ ํตํด ์๋ก ๋ค๋ฅธ ๋์์ธ์ด ์ฅ์ ์ ๋๊ณ ๊ฒฝ์ํ๊ฒ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
@Turbo87 ์ข์ ์ ์์ ๋๋ค. ๋ชฉ๋ก์ ๋ง์ด๊ทธ๋ ์ด์ ๊ฐ์ด๋๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค. ๊ธฐ์กด ํจํด๊ณผ ์๋ก์ด API๋ก ๋์ผํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค์ผ ํฉ๋๋ค.
didReceiveAttrs()
์ ๊ฒฝ์ฐ๋ ๊ทํ๊ฐ ์ ๊ธฐํ ์ดํ๋ก ๊ตฌ์ฒด์ ์ผ๋ก ๋ค๋ฃจ๊ฒ ์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ฌ๋๋ค์ ์ ๋ฌ๋ ์ธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ ์์ ์ํ๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํด ์ด ํํฌ๋ฅผ ์ฌ์ฉํ์ง๋ง ์ค์ ๋ก๋ ์ด๋ฌํ ํํฌ์์ ๋ถํ์ํ ์์
์ ์๋นํ ์ํํ ์ ์์์ ์๋ฏธํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๊ฒฐ์ฝ ์ฌ์ฉ๋์ง ์๋ ๊ฐ์ ์ด๊ธฐํํ๋ ๊ฒฝ์ฐ์
๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฌผ๋ก ์ฌ๋๋ค์ ๋ ๋๋ง ํซ ํจ์ค์ ์๋ ์ด๋ฌํ ํํฌ์์ ์ถฉ๊ฒฉ์ ์ธ ์ผ์ ํ๊ฒ ๋ฉ๋๋ค.
๋์์ "ํธ์ ๊ธฐ๋ฐ" ์ด๊ธฐํ์์ "ํ ๊ธฐ๋ฐ" ์ด๊ธฐํ๋ก ์ ํํ๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ตฌ์ฑ ์์ ์์ฑ ๊ฐ์ ์์ฑํ๊ฑฐ๋ ์ด๊ธฐํํ๊ธฐ ์ํด ์ผ๋ถ ๊ณ์ฐ์ ์ํํ๋ ค๋ ๊ฒฝ์ฐ ๋์ ์ถ์ ๋ ๊ณ์ฐ ์์ฑ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ค์ ๋ก ์ฌ์ฉ๋๋ ๊ฐ์ ๋ํด์๋ง ์์ ์ด ์ํ๋ฉ๋๋ค. ์์:
๋์ :
import Component from "@ember/component";
import { computed } from "@ember/object";
export default Component.extend({
didReceiveAttrs() {
this.set('firstName', this.attrs.firstName || 'Tobias');
this.set('lastName', this.attrs.lastName || 'Bieniek');
},
fullName: computed('firstName', 'lastName', function() {
return `${this.firstName} ${this.lastName}`;
})
});
์ด ์์ ์ ์ํ:
import Component, { tracked } from "@glimmer/component";
export default class extends Component {
<strong i="27">@tracked</strong> get firstName() {
return this.args.firstName || 'Tobias';
}
<strong i="28">@tracked</strong> get lastName() {
return this.args.lastName || 'Bieniek';
}
<strong i="29">@tracked</strong> get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
์ฒ์์๋ ์ด์ ๋ํด ํ์์ ์ด์์ง๋ง @wycats ๊ฐ ์ ๋ฅผ ์ค๋ํ๊ณ ์ง๋ 1๋
๋์ ํฐ Glimmer.js ์ฑ์ ๊ตฌ์ถํ ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด didReceiveAttrs
๋ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ง๋ ์ ์ด ์์ต๋๋ค. ๋ ํจ์จ์ ์ธ ๊ณ์ฐ ์์ฑ์ผ๋ก ๋ชจ๋ธ๋งํ ์ ์์ต๋๋ค.
@tomdale ๋๋ถ๋ถ์ ๊ฒฝ์ฐ didReceiveAttrs
๊ฐ ํ์ํ์ง ์๋ค๋ ๋ฐ ๋์ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋๋ก๋ ๋ถ๋ชจ๋ก๋ถํฐ ์ ๋ฌ๋ ์์ฑ ์ค ํ๋์ ๋ํด ๊ด์ฐฐ์๋ฅผ ์์ฑํ ํ์๊ฐ ์์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์์ฑ โโ์ค ํ๋๊ฐ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ajax ์์ฒญ์ ์์ํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์? ๋๋ getter์ ๊ทธ๋ฐ ์ข
๋ฅ์ ๋ถ์์ฉ์ ์ถ๊ฐํ๊ณ ์ถ์ง ์์ต๋๋ค.
์, ๋น์ทํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์๊ฐํ๊ณ ์์ต๋๋ค. ํ ๊ฐ์ง ์๋ ์ ๋๋ฉ์ด์
์
๋๋ค. collapsed
๊ฐ true
์์ false
๋๊ณ ๋ค๋ฅธ ๋ฐฉํฅ์ผ๋ก ๋ณ๊ฒฝ๋ ๋ ์ ๋๋ฉ์ด์
์ ์์ํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. glimmer ๊ตฌ์ฑ ์์์ ์ด๋ป๊ฒ ์๋ํฉ๋๊น?
@turbo87 @Gaurav0 ์ ์ข์, ์์คํ
์ด ์๋ํ๋ ์ด์ ๋ ๋ชจ๋ ๋๊ธฐ์์ธ didReceiveAttrs
์์ ์ํํด์๋ ์ ๋๋ ์ฑ๋ฅ ํ๊ฑด ์ด๊ธฐ ๋๋ฌธ์
๋๋ค! ์ ๋๋ฉ์ด์
์ด๋ ๋คํธ์ํฌ ์์ฒญ๊ณผ ๊ฐ์ ๋ถ์์ฉ์ด ์๋ ๋ชจ๋ ๊ฒ์ didInsertElement
๋๋ didUpdate
์ ๊ฐ์ ๋น๋๊ธฐ ํํฌ๋ก ์์ฝํด์ผ ํฉ๋๋ค.
didInsertElement
๋ ์์ ์์์ ์ ๋ง์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. didUpdate
๋ ๊ตฌ์ฑ ์์๊ฐ ๋ค์ ๋ ๋๋ง๋ ๋๋ง ํธ๋ฆฌ๊ฑฐ๋๋ ๊ฒ ๊ฐ์ต๋๋ค. ๋ง์ต๋๊น? ํ์ง๋ง ์ค์ ๋ก ๋ ๋๋ง์ ํด๋น ์์ฑ์ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์? ๊ทธ๋ฌ๋ฉด ์ธ์๋ฅผ ๋ณ๊ฒฝํ ๋ ๊ตฌ์ฑ ์์๊ฐ ๋ค์ ๋ ๋๋ง๋์ง ์์ผ๋ฏ๋ก didUpdate
๊ฐ ํธ์ถ๋์ง ์์ต๋๋ค. ๐ค
๋ํ didInsertElement
๋ ๋ฌด์ธ๊ฐ๋ฅผ ์ค์ ํ๊ณ ๋ค์ ๋ ๋๋งํ๋ฉด Glimmer์์ ํ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
@Turbo87 didUpdate
๊ฐ ํธ์ถ๋ ๋ ์คํด๊ฐ ์์ ์ ์์ต๋๋ค. ์ด ํํฌ๋ ํ
ํ๋ฆฟ์ ์ฌ์ฉ๋ ์ถ์ ์์ฑ ๋๋ ์ ๋ฌ๋ ์ธ์๊ฐ ๋ณ๊ฒฝ๋ ๋ ํธ์ถ๋ฉ๋๋ค. ์ด ์๋ฅผ ์ฐธ์กฐํ์ญ์์ค: http://tinyurl.com/y7osxpy2. ์์ ๊ตฌ์ฑ ์์๊ฐ ์ธ์๋ฅผ ์ ๋ฌํ๋ฉด ํ์ ๊ตฌ์ฑ ์์๋ ํด๋น ์ธ์๋ฅผ "์ฌ์ฉ"ํ ์ ์ด ์๋๋ผ๋ ํธ์ถ๋ didUpdate
ํํฌ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
@Gaurav0 ๊ณจ๋๋ฅผ ์ฎ๊ธฐ๊ณ ์์ต๋๋ค. ;) ๊ทํ์ ์๋ didInsertElement
์์ ๋ฐ์ํ ๊ฒฝ์ฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์๋ ์ธ์ ๋ณ๊ฒฝ์ ๋ํ ์๋ต์ผ๋ก ajax ์์ฒญ์ ์์ํ์ต๋๋ค. ๋์์ ์์ฑ์ ๋๊ธฐ์ ์ผ๋ก ์ค์ ํ๋ ค๋ฉด ์ง์ฐ ๊ฒํฐ๋ฅผ ์ฌ์ฉํ์ฌ ๋์ผํ ๋์์ ๋ชจ๋ธ๋งํ ์ ์์ด์ผ ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ajax ์ดํ์ ์์ฑ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ค์ ํด์ผ ํ๋ ๊ฒฝ์ฐ ๋ค๋ฅธ ์ด๋ฒคํธ ๋ฃจํ์์ ๋ฐ์ํ๋ฏ๋ก ์ค๋ฅ๊ฐ ํธ๋ฆฌ๊ฑฐ๋์ง ์์ต๋๋ค.
์ข์, ๋์๊ฒ ์ถฉ๋ถํด ๋ณด์ธ๋ค. ์ด์จ๋ ์ด ํน์ ์ฌํญ์ ํ์ฅํ๊ณ ์ถ์ง๋ ์์์ต๋๋ค. ๋ค๋ง ์ฒ ์ ํ ๋ง์ด๊ทธ๋ ์ด์ ๊ฐ์ด๋๊ฐ ํ์ํ๋ค๋ ์ ์ ๊ฐ์กฐํ๊ณ ์ถ์์ ๋ฟ์ ๋๋ค. :)
@tomdale ์ด๊ฒ ์์ง ์ต์ ์ํ์ธ๊ฐ์? ํ๋์ ๋นํ์ฑ ์ํ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
@tomdale ์ข์ต๋๋ค. ์๋๋ฆฌ์ค๋ ํน์ ์์ฑ์ด ๋ณ๊ฒฝ๋๊ณ ํด๋น ์์ฑ๋ง ๋ณ๊ฒฝ๋์์ ๋
@Gaurav0 ์์ฑ์ด ๋ณ๊ฒฝ๋๋ ์์ธ์ ๋ฌด์์ ๋๊น? DDAU์ ์ด์ด ์์ฑ์ ๋ณ๊ฒฝํ๊ฒ ํ๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ๋ด๋นํ๋ ์ฝ๋๊ฐ AJAX ์์ฒญ์ ์์ํ๋ ๊ฒ๋ ๋ด๋นํด์ผ ํ๋ค๊ณ ์๊ฐํฉ๋๋ค.
์์ฑ์ด ์์ ๊ตฌ์ฑ ์์/์ปจํธ๋กค๋ฌ์์ ๋ณ๊ฒฝ๋ฉ๋๋ค. ๋ค์ฐ.
@Gaurav0 @tomdale ์ด ์ฌ์ฉ ์ฌ๋ก์ ๋ ๋ค๋ฅธ ์๋ ๋ค๋ฅธ "๊ฐ์ฒด"์ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํ๋ (๋๋ถ๋ถ) "DOM์ด ์๋" ๊ตฌ์ฑ ์์ ์งํฉ์
๋๋ค. ํ์ฌ ์๋ ์ ๋จ์ง ์ง๋์ ๋ด์ฉ์ ์ ์ธ์ ์ผ๋ก ๊ตฌ์ฑํ ์ ์๋ ember-leaflet/ ember-composability-tools ์
๋๋ค. ๋์๊ฒ ์ด๊ฒ์ didReceiveAttrs
๋๋ observer
๊ธฐ๋ฅ์ด ์๊ธฐ ๋๋ฌธ์ ํ์ฌ Glimmer ๊ตฌ์ฑ ์์์์ ๊ฐ๋ฅํ์ง ์์ ๊ฒ ๊ฐ์ต๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์ต๋๊น?
@nickschot ์ ๋ ์ด๊ฒ์ ๋ฐ์๋ค์ผ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ค์ ๋ก ๋ค์ํ ์ปค๋ฎค๋ํฐ ์ ๋์จ ๋ฐ ์ฌ์ฉ ์ฌ๋ก์ ์ค๊ณ ๊ณผ์ ์์ ๊ฐ์ฌ๋ฅผ ์ํํ์ผ๋ฉฐ ๊ตฌ์ฒด์ ์ผ๋ก ember-leaflet
๋ค๋ฃจ์์ต๋๋ค.
ember-leaflet
/ ember-composability-tools
๋ฅผ ํํค์ณ ๋ณด๋ฉด ์ค์ ๋ก didReceiveAttrs
๋๋ didUpdate
๋๋ ์ด์ ๊ฐ์ ์๋ช
์ฃผ๊ธฐ ํํฌ๋ฅผ ์ค์ ๋ก ์ฌ์ฉํ์ง ์๋๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค. . ๊ตฌ์ฑ ์์๊ฐ ๋ถ๋ชจ(๊ทธ๋ฆฌ๊ณ ๊ถ๊ทน์ ์ผ๋ก ๋ฃจํธ ๋ ๋๋ง ๋ถ๋ชจ)์ ๋ฑ๋ก/๋ฑ๋ก ์ทจ์ํ๋ ค๋ฉด ์ค์ ๋ก init
๋ฐ willDestroy
ํํฌ๋ง ํ์ํฉ๋๋ค. ์ด๊ฒ์ Glimmer ๊ตฌ์ฑ ์์์ constructor
๋ฐ willDestroy
ํํฌ์์ ์ํํ ์ ์์ต๋๋ค. ๋ฃจํธ ์์ ๊ตฌ์ฑ์์๋ didInsertElement
๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด _ํ์ํ์ง๋ง {{did-insert}}
์์ ์๋ฅผ ํตํด ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก {{did-insert}}
/ {{did-update}}
๋ฅผ ์ฌ์ฉํ์ฌ DOM ์์์ ์์ฑ ์๋ฅผ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ค์ ์๋ ์ถ์ ๋๋ฏ๋ก ๊ฐ์ ์ฌ์ฉํ๋ฉด ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ๋ค์ ์คํ๋ฉ๋๋ค. ์ํ๋ ๊ฒฝ์ฐ ๊ณ ์ ํ ์ฌ์ฉ์ ์ง์ ์์ ์๋ฅผ ์์ฑํ ์๋ ์์ผ๋ฉฐ ์ด ๋ํ ์ํํ ์ ์์ต๋๋ค.
ํฌ๋ฏธํ ๋น์ ๊ตฌ์ฑ ์์ ์ ์์ต๋๋ค ์ด๋ ์ ๋ ๊ด๋ จ์ด ์ฌ์ฉ ์ฌ๋ก๊ฐ์๋ค - A๋ ๊ฐ์ "๊ฐ์ง๊ธฐ๋ฅผ ๋ ๋๋ง" ์ด ํ๋ ์์ ember-google-maps
์ถ๊ฐ ๊ธฐ๋ฅ. ์ด๊ฒ์ ํจ์ฌ ๋ ์ผ๋ฐ์ ์ด๋ฉฐ(์ด๊ฒ์ ํ ๋ฒ๋ง ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ํ์ธ๋จ) DOM์ ๋ณด๊ธฐ ์ํด MutationObserver
๋๋ ์คํ ๊ธฐ๋ฅ์ ์ ํํ๋ ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ํตํด ํด๊ฒฐํ ์ ์์ต๋๋ค didUpdate
/ didRender
ํํฌ. ์ ๋ ์ค์ ๋ก ๋ฒ์ฉ <RenderDetector>
๊ตฌ์ฑ ์์๊ฐ ์ด๋ฌํ ๋ชจ๋ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ฒ๋ฆฌํ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์๋ํ๋ฉด ๊ตฌ์ฑ ์์ ํ์ ํธ๋ฆฌ์์ ์
๋ฐ์ดํธ๋ฅผ ๊ฐ์ํ๋ ๊ธฐ๋ฅ์ ์ฐพ๊ธฐ ์ฌ์ด ๋จ์ผ ๊ตฌ์ฑ ์์๋ก ๋ถ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค.
@pzuraq ์ค๋๋ง ์ด์ง๋ง ์ด ์์ญ์์ ์์ ์ ๋ฐ์ดํธ์ ๋๋ค. ๋ด ์ฌ์ฉ ์ฌ๋ก์ ๊ฒฝ์ฐ ์ด๋ฌํ ๊ตฌ์ฑ ์์ ๋ด์ DOM์ด ์ ํ ์๊ธฐ ๋๋ฌธ์ ์์ ์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ด๊ฐ ํ์ฌ ํ ์ผ์ didUpdate ํํฌ๋ฅผ ๋ค์ ํ์ฑํํ๋ ํฌ๋ฏธํ ์๋ฏธ ์ฒด๊ณ๋ฅผ ๊ฐ์ง ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๋๋ค.
@nickschot ์ค์ ๋ก ๋์ฐ๋ฏธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ํฌํผ๋ ์ต์ํ๋ค๋ฉด React์ useEffect
์ ์ ์ฌํ ๋ถ์์ฉ๊ณผ ์๋ฌด ๊ฒ๋ ๋ฐํํ์ง ์์ ์ ์์ต๋๋ค(์์ ์๋ useLayoutEffect
์ ๋ ์ ์ฌํฉ๋๋ค).
ํด๋์ค ๊ธฐ๋ฐ ๋์ฐ๋ฏธ API๋ ์ฝ๊ฐ์ ์์ ์ด ํ์ํฉ๋๋ค. ์ด์์ ์ผ๋ก๋ ์ต์ข ์ฌ์ฉ์๊ฐ ์์ ์ API์ ์ง๋ฉดํ๋ ๊ฒ๊ณผ ์ผ์นํด์ผ ํฉ๋๋ค(๊ฒ๋ค๊ฐ ๋ค์ ๋์์ธํ ์ ์๋๋ก ๋์ฐ๋ฏธ ๊ด๋ฆฌ์๋ฅผ ๋์ ํด์ผ ํจ). ํ์ง๋ง ํ์ฌ API๋ ๋ชจ๋ ๊ฒ์ ์ ๊ณตํด์ผ ํฉ๋๋ค. ์ํ๋ ๋ถ์์ฉ์ ๋ฌ์ฑํ๋ ๋ฐ ํ์ํ ๋ฅ๋ ฅ์ ๋๋ค.
@pzuraq ์ด๋ป๊ฒ ์๋ํฉ๋๊น? ์ฌ์ฉ์ ์ง์ ๋์ฐ๋ฏธ๋ฅผ ๋ง๋ค์ด์ผ ํ๋์ ์๋๋ฉด ๋์ฐ๋ฏธ๊ฐ ๋ง๋ค๊น์?
๊ตฌ๋ฌธ์ด ์ด๋ ์ต๋๊น?
{{concat (did-insert this.myAction)}}
์ธ์๋ฅผ ์ ๋ฌํ๊ณ "์์ "ํ์ง ์๋ ๊ฒ์ฒ๋ผ ๋๊ปด์ง๋๋ค.
์๋๋ฉด ์์ ์ ๋์ ๋์ฐ๋ฏธ
{{my-did-insert this.myAction}}
๊ทธ๋ ๋ค๋ฉด ๋ฌธ์ ๋ฐ ์์ ์ ๋ํ ๋งํฌ๋ฅผ ๊ฒ์ํ์ญ์์ค. ํด๋์ค ๋์ฐ๋ฏธ์ ํ์ฌ ๊ณต๊ฐ API์๋ compute
๋ฐ recompute
์๊ณ ๊ตฌ์ฑ ์์ ์๋ช
์ฃผ๊ธฐ์ ๋ํด์๋ ์๋ฌด ๊ฒ๋ ์์ต๋๋ค.
์ด๋ฆฌ์์ ์ง๋ฌธ์ ์ฉ์ํด ์ฃผ์ญ์์ค. ๊ทธ๋ฌ๋ ์ผ๋ฐ Ember ์ฌ์ฉ์์๊ฒ ์ด ๋ฌธ์ ๋ ๋งค์ฐ ๋น๋ฐ์ค๋ฝ๊ณ ๋ฌธ์๊ฐ ๋ถ์กฑํ๊ณ ํฉ์ด์ ธ ์์ต๋๋ค.
์๋๋ฉด ์์ ์ ๋์ ๋์ฐ๋ฏธ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ์ ์ํ๊ณ ์์ต๋๊น?
๋ง์์. ์๋ฅผ ๋ค์ด @ember/render-modifiers
API๋ฅผ ๋ชจ๋ฐฉํ๋ ember-render-helpers ์์ ์ด์ ๋ํ ์๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
์ผ๋ฐ์ ์ผ๋ก compute
๋ ๋์ฐ๋ฏธ๊ฐ ํ
ํ๋ฆฟ/๊ณ์ฐ์ ์ฒ์ ์ฝ์
๋ ๋ ํธ๋ฆฌ๊ฑฐ๋๊ณ ์ธ์๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ค์ ํธ๋ฆฌ๊ฑฐ๋ฉ๋๋ค. ๋ํ 3.13+์์ ์๋ ์ถ์ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด {{did-insert}}
ํ์ ๋ฐ๋ผ ๋ฌด์ธ๊ฐ๊ฐ ํ์ํ ๊ฒฝ์ฐ ๋ค์์ ์ํํ ์ ์์ต๋๋ค.
export default class didInsert extends Helper {
compute(fn) {
if (!this.rendered) {
fn();
this.rendered = true;
}
}
}
๊ทธ๋ฆฌ๊ณ ๊ฑฑ์ ํ์ง ๋ง์ธ์. ์ฝ๊ฐ ๋ต๋ตํ๊ณ ๋น๋ฐ์ค๋ฌ์ ๋ณด์ผ ์ ์๋ค๋ ์ ์ ์ดํดํฉ๋๋ค. ๊ทธ๊ฒ์ด ์ต์ฒจ๋จ/์นด๋๋ฆฌ์ ์ธก๋ฉด์ ์๋ ํน์ฑ์ ๋๋ค. ์ฐ๋ฆฌ๋ ์์ง ๋ชจ๋ ์๋ก์ด ํจํด์ ๋ฌธ์ํํ์ง ์์์ผ๋ฉฐ ์ฐ๋ฆฌ๋ ๊ทธ๊ฒ์ ๋ํด ์์ ํ๊ณ ์์ต๋๋ค ๐
Octane์ด ์ถ์๋ ์ง๊ธ ์ด ๋ฌธ์ ๋ฅผ ์ข ๋ฃํ ์ ์๋ค๊ณ ์๊ฐํฉ๋๋ค ๐
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
@dbbk ์ฐ๋ฆฌ๊ฐ
{{...attributes}}
ํ์๋ก ํ์ง ์๋ ๊ฐ์ฅ ํฐ ์ด์ ๋ ์ฐ๋ฆฌ๊ฐ curlies๋ฅผ ํ์๋ก ํ๋ ๋ค๋ฅธ ๊ฒฝ์ฐ์ ๊ฐ์ด ์ผ๋ฐ ์์ฑ๊ณผ ๊ตฌ๋ฌธ์ ์ผ๋ก ๋ชจํธํ์ง ์๊ณ 4๊ฐ์ ์ ์ ๋ฌธ์๊ฐ ํ์ดํํ๊ธฐ ์ฝ๊ณ ์๊ฐ์ ์ผ๋ก ๋ ์๋๋ฝ๊ฒ ๋ณด์ด๊ธฐ ๋๋ฌธ์ ๋๋ค.๋ํ ์ฌ๋๋ค์ด
attributes
๊ฐ ๋ฒ์ ๋ด ์์ฑ์ด๋ผ๊ณ ๊ฐ์ ํ ์ ์๋ค๊ณ ์๊ฐํ์ง๋ง ๊ทธ๋ ์ง ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํด๋น ๊ตฌ๋ฌธ์์ ์ ์ํ๋ ๊ฒ์ฒ๋ผ<SomeComponent something={{attributes}} />
์ํํ ์๋ ์์ต๋๋ค. ๋ํ ์คํ๋ ๋ ๊ตฌ๋ฌธ์ด ์๋ํ์ง ์์ ๋ ๋ค๋ฅธ ์์น์์ ์๋ํ๋ค๋ ๊ฒ์ ๋ ๊ฐ๋ ฅํ๊ฒ ์์ํฉ๋๋ค.@arguments
๋ฅผ ๋ชจ๋ ํน์ ํ ํ๋ฆฟ ๋ฐ์ธ๋ฉ์ผ๋ก ์ฑํํ๊ณ ํธ๋ค๋ฐ์...
์คํ๋ ๋ ๊ตฌ๋ฌธ์ ์ถ๊ฐํ์๋ ์ ์์ด ์์์ง๋ง ์ฆ๊ฐ์ ์ธ ๋ก๋๋งต์ ์๋ ์ค๊ณ ๋ฐ ๊ตฌํ์ด ํ์ํฉ๋๋ค. ๋ฏธ๋์...attributes
๋ฅผ{{...@attributes}}
๋๋ ์ด์ ์ ์ฌํ ๊ฒ์ผ๋ก ๋ฐ๊พธ๋ฉด ์ ํ ๋๋ผ์ง ์์ ๊ฒ์ ๋๋ค.@Gaurav0 Glimmer ๊ตฌ์ฑ ์์ API๋ Ember ์ฑ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ฑํ๋๊ธฐ ์ ์ RFC ํ๋ก์ธ์ค๋ฅผ ๊ฑฐ์น๊ฒ ๋ฉ๋๋ค. ์ฌ์ฉ์ ์ง์ ๊ตฌ์ฑ ์์ ๊ด๋ฆฌ์ ์ ๊ทผ ๋ฐฉ์์ ํ ๊ฐ์ง ์ข์ ์ ์ "์ฐจ์ธ๋" API๋ฅผ ์ ์ํํ์ง ์์ง๋ง ์ ๋์จ ์์ฝ์์คํ ์ ํตํด ์๋ก ๋ค๋ฅธ ๋์์ธ์ด ์ฅ์ ์ ๋๊ณ ๊ฒฝ์ํ๊ฒ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ค.
@Turbo87 ์ข์ ์ ์์ ๋๋ค. ๋ชฉ๋ก์ ๋ง์ด๊ทธ๋ ์ด์ ๊ฐ์ด๋๋ฅผ ์ถ๊ฐํ๊ฒ ์ต๋๋ค. ๊ธฐ์กด ํจํด๊ณผ ์๋ก์ด API๋ก ๋์ผํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค์ผ ํฉ๋๋ค.
didReceiveAttrs()
์ ๊ฒฝ์ฐ๋ ๊ทํ๊ฐ ์ ๊ธฐํ ์ดํ๋ก ๊ตฌ์ฒด์ ์ผ๋ก ๋ค๋ฃจ๊ฒ ์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ฌ๋๋ค์ ์ ๋ฌ๋ ์ธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ ์์ ์ํ๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํด ์ด ํํฌ๋ฅผ ์ฌ์ฉํ์ง๋ง ์ค์ ๋ก๋ ์ด๋ฌํ ํํฌ์์ ๋ถํ์ํ ์์ ์ ์๋นํ ์ํํ ์ ์์์ ์๋ฏธํฉ๋๋ค. ์๋ฅผ ๋ค์ด ๊ฒฐ์ฝ ์ฌ์ฉ๋์ง ์๋ ๊ฐ์ ์ด๊ธฐํํ๋ ๊ฒฝ์ฐ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฌผ๋ก ์ฌ๋๋ค์ ๋ ๋๋ง ํซ ํจ์ค์ ์๋ ์ด๋ฌํ ํํฌ์์ ์ถฉ๊ฒฉ์ ์ธ ์ผ์ ํ๊ฒ ๋ฉ๋๋ค.๋์์ "ํธ์ ๊ธฐ๋ฐ" ์ด๊ธฐํ์์ "ํ ๊ธฐ๋ฐ" ์ด๊ธฐํ๋ก ์ ํํ๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ตฌ์ฑ ์์ ์์ฑ ๊ฐ์ ์์ฑํ๊ฑฐ๋ ์ด๊ธฐํํ๊ธฐ ์ํด ์ผ๋ถ ๊ณ์ฐ์ ์ํํ๋ ค๋ ๊ฒฝ์ฐ ๋์ ์ถ์ ๋ ๊ณ์ฐ ์์ฑ์ ์ฌ์ฉํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ์ค์ ๋ก ์ฌ์ฉ๋๋ ๊ฐ์ ๋ํด์๋ง ์์ ์ด ์ํ๋ฉ๋๋ค. ์์:
๋์ :
์ด ์์ ์ ์ํ:
์ฒ์์๋ ์ด์ ๋ํด ํ์์ ์ด์์ง๋ง @wycats ๊ฐ ์ ๋ฅผ ์ค๋ํ๊ณ ์ง๋ 1๋ ๋์ ํฐ Glimmer.js ์ฑ์ ๊ตฌ์ถํ ๊ฒฝํ์ ๋ฐ๋ฅด๋ฉด
didReceiveAttrs
๋ํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๋ง๋ ์ ์ด ์์ต๋๋ค. ๋ ํจ์จ์ ์ธ ๊ณ์ฐ ์์ฑ์ผ๋ก ๋ชจ๋ธ๋งํ ์ ์์ต๋๋ค.