Last active
July 30, 2016 22:24
-
-
Save visualjeff/8c04d19680293fdb2af7c69023022563 to your computer and use it in GitHub Desktop.
Ember Component Learnings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ember Component Learnings: | |
========================== | |
Don't ever assign a dynamic value to a id or name attribute of a field | |
Don't share state between components. Always reset or init properties via the init method. Same for mixins. | |
Warning: | |
======== | |
Because components are sealed from outside events. It challenging to | |
get them to refresh on command. To pull this off you essentially need | |
them to observe a property on a controller in order to get them to refresh. | |
Property changes, component refreshes. | |
Ember component notes from ember conf 2016 | |
========================================== | |
REMINDER or WARNING: | |
Don't share state between components. Always reset or init properties via the init method. Same holds true for mixins. | |
Composable Component notes: | |
--------------------------- | |
Avoid muting state in child components. The parent should be the owner. Let the child send an action up to the parent. | |
NOTE: Services can also own their own data. Singleton need to be moved into services because routable components will be stateless. Routable components will replace controllers. They will still decorate the data associated with the template. Implementation will change. | |
To future proof against this change: | |
-Move route level templates into a top level component. | |
-In the future, components invocation to the route | |
-Move statefull bits to service | |
-Move stateless bits to component | |
Actions: | |
-------- | |
Classic (string) vs New-style or closure actions (Really just a Javascript function). | |
NOTE: Classic actions force you to use sendAction in your components. This can be hard to debug. Nothing is returned. | |
New style actions look like: | |
get(this, 'submit')(...args); | |
The benefit to new style is you now have return values! Helpful with Asynchronsis actions. | |
get(this, 'save')(item).then((savedItem) => // do stuff); | |
NOTE: New style actions defined on the controller DO NOT bubble up. | |
ember install ember-route-action-helper | |
Uses "route-action" to facilitate move new style actions to the route. | |
Services: | |
--------- | |
For long lived singleton state. | |
Computed properties: | |
-------------------- | |
Suggestion to use rwj's computed annotation. Might be helpful. | |
Why use them compouted properties: | |
1. Business logic | |
2. Reusable | |
3. Change is implicit (sometimes hard to understand why something changed) | |
Computed properties can also be used in the model. | |
Helpers: | |
-------- | |
Easy to implement your own. Examples include repeat or capitalize. | |
Why use them: | |
1. Express UI logic | |
2. Composable | |
3. Simple mental model | |
4. Can be used as an action | |
5. No hooks available. Yet. | |
Examples: | |
add, component, concat, dasherize, eq, pipe | |
To get pipe or dasherize: | |
ember install ember-composable-helpers | |
FYI: The {{component}} helper expects the component name as the second parameter, and will dynamically render out the component by that name. An arbitrary number of parameters may follow the component name. | |
{{component myComponentName param1=param1 param2=param2 ...}} | |
For example: | |
// food/component.js | |
import Ember from 'ember'; | |
const { Component, computed, get } = Ember; | |
export default Component.extend({ | |
tastyComponentName: computed('food.taste', { | |
get() { | |
let foodTaste = get(this, 'food.taste'); | |
return `food/${foodTaste}-food`; | |
} | |
}) | |
}); | |
{{! food/template.hbs }} | |
{{component tastyComponentName food=food}} | |
We can forgo the CP altogether and use Handlebars subexpressions to keep all logic within the template. | |
The Ember helper concat is one of the helpers we use fairly often. It's common to name components based on a value of an attribute. | |
{{! food/template.hbs }} | |
{{component (concat "food/" food.taste "-food") food=food}} | |
The concat helper replaces the computed property entirely. If the value of food.taste is sweet, then the helper will output food/sweet-food. Sometimes, we have to work with camelized values, and using dasherize will convert them to a more desired format. In this case, if the value of food.taste is SuperSour, then our rendered component will be food/super-sour-food. | |
{{component (concat "food/" (dasherize food.taste) "-food") food=food}} | |
Components: | |
----------- | |
Component hooks: | |
NOTE: Don't ever use didRender hook to update attrs unless you like infinite loops. | |
Hooks include: | |
initial Render External attr changed Internal value changed | |
-------------- --------------------- ---------------------- | |
init didUpdateAttrs | |
didReceiveAttrs didReceiveAttrs | |
willRender willUpdate willUpdate | |
didInsertElement didUpdate didUpdate | |
didRender didRender didRender | |
On initial render you should use init and didInsertElement. | |
On external attr changed you should use didUpdate. | |
On internal value change you should use didUpdate. | |
Observers? | |
---------- | |
Don't use them! | |
ember process is like game processing: | |
1. application state Ember ==> 2. HTMLBars ==> 3. Glimmer | |
|| | |
4. Dom API's | |
|| | |
5. Browser | |
|| | |
6. Screen | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment