Reputation: 2465
I am confused about what is better approach, should we prefer to communicate between components, components/controllers via data or actions more?
Here is an example: I have a file uploader component (wrapping the jquery plugin) and the way I have the component setup is like this:
1) the controller that contains the file uploader component defines a property via which two entities are going to share information about the file being uploaded
//some controller template
//where uploadedFiles is a property of the context controller
{{file-uploader uploadedFiles=uploadedFiles}}
2) this property is passed to the component and the component populates it with errors/progress etc as we initiate the upload. The structure of this data object looks like:
{
'file': file object we get from plugin
'errors': [],
'progress':10,
....
}
This component also does some basic file validation such as file type and size. When these errors happen, we populate the data object with errors. Now I am debating - should I have an action that gets triggered every time these custom validations fails, or is it ok to have an observer in the controller to inspect the data objects and then trigger whatever action it needs to.
I am leaning more towards communicating things via data itself because it keeps the interface of communication cleaner, but I also understand it cost an overhead of observers.
Passing actions on the other hand avoids having observers but I don't fully agree with it because then we might have 10 other situations where we might feel like passing "action" is the right choice and then pollute the component code(when it can be communicated via data).
I do agree that in certain cases we must have to pass actions, but given the choice that things can be communicated via bound data, is action the better choice?
Thanks.
Upvotes: 1
Views: 87
Reputation: 3758
Before we discuss Observers, the question we're really asking is:
Should Components mutate their arguments?
If we think of the Component as a function (we pass it data, it does something), we can go up a level of abstraction:
Should functions mutate their arguments?
This is an old question. It's really about imperative programming (mutable data) vs functional programming (immutable data). Both Ember and React have been moving towards an immutable style, where child Components do not mutate the arguments they're passed. Some examples of this:
So, the community best practice is to use actions to communicate from child Components to their parent contexts. And to communicate to child Components via data.
Now, suppose you were to mutate the data directly in the Component-- and you want to do something in response, in the parent Controller-- the reason Observers come up is that we need some way to cause side effects based on a change in data. Sometimes you have the option of using a Computed Property instead.
What's so bad about observers? Unlike Computed Properties, they're synchronous and eager-- this one of the things that makes Observers trickier than Computed Properties, despite the fact that they both react to changes in data. In addition to Lauren Tan's article (that kushdilip also linked to), Stefan Penner does a great job explaining this.
If you're concerned about polluting Component code with a ton of actions, I'd check out ember-composable-helpers and the mut
helper in Ember 2. A lot of action code can actually be pushed into your templates.
Upvotes: 1
Reputation: 7906
I feel, you better go with actions. I am using Ember for around two years and as per my experience, observers are unpredictable and really hard to debug.
If your observer is just one line than no problem. But the amount code almost always grows, so it will tend to become more and more complex.
Action will give you better control over parameters, cleaner interface and it'll be far easier to follow and predict the data flow.
In our ember apps, we have hundreds of observers across controllers and we slowly trying to clean up as much as possible.
I am not against observers but they should be used only if you don't have any other way to achieve something. Here is a broad explanation from a developer at Dockyard(Ember Experts) on why observers are anti patterns and should be avoided.
Upvotes: 4