Reputation: 2604
Im kinda new in Ember world.
When working with a large library of unknown components, Im having difficulties tracking what params they accept.
Let's put an fake example:
Template ViewA
{{component-article
title="article.title"
preview="article.preview"
image="article.imgUrl"
content="article.content"}}
Template ViewB
{{component-article
title="article.title"
content="article.content"}}
As we see, two templates are using my component-article component.
My issue comes when I want to use this component. How do i know the properties my **component-article is exposing?**
If Im Im new to the project, I have never seen nor use component-article, I have no idea what properties is accepting. In fact, I need to dig into the template, do a find in the project and see how others templates are calling it or what not.
Is there any way to explicitly set in the component-article.js file what properties Im allowing to come in?
The positionalParams property seems to almost serve this purpose but it does not.
Is there any property in the component that would allow me to set explicitly what params are accepted by the component? Any convention on this?
Example:
export default Component.extend({
layout,
acceptProperties: ['title', 'content', 'preview', 'image']
});
Upvotes: 2
Views: 170
Reputation: 11
I like to use the ember-prop-types addon for this use case. This allows you to see the available properties, the types of each property that the component accepts, and you can also set default values.
Here is a small example of what it can do:
import { Component } from '@ember/component';
import { PropTypes } from 'ember-prop-types';
export default Component.extend({
// Defines the properties for the component
propTypes: {
// Must be a 'string'
name: PropTypes.string,
// Must be a 'number' and it's required
age: PropTypes.number.isRequired,
// Must be one of the values in the array
favoriteColor: PropTypes.oneOf(['red', 'blue', 'green'])
},
// Defines the default values for the properties if not passed in
getDefaultProps () {
return {
name: 'New User',
age: 99
}
}
});
Upvotes: 1
Reputation: 8724
I feel your pain on this. There's been work done recently to support named arguments to components that's helped to disambiguate passed params from a number of other sources within templates that merged in 3.1. You can see the rfc here for the rationale. See this blog post for a more thorough explanation.
In short, you can access passed args as: {{@arg}}
, such that you can know in the template that this was passed to the component.
This helps but isn't the complete. I have found that the convention in an understandable component is to include all the arguments at the top of the component file with a header comment. Such an example can be seen in ember-power-select (a popular select addon):
// Options
searchEnabled: fallbackIfUndefined(true),
matchTriggerWidth: fallbackIfUndefined(true),
preventScroll: fallbackIfUndefined(false),
matcher: fallbackIfUndefined(defaultMatcher),
loadingMessage: fallbackIfUndefined('Loading options...'),
noMatchesMessage: fallbackIfUndefined('No results found'),
searchMessage: fallbackIfUndefined('Type to search'),
closeOnSelect: fallbackIfUndefined(true),
defaultHighlighted: fallbackIfUndefined(defaultHighlighted),
typeAheadMatcher: fallbackIfUndefined(defaultTypeAheadMatcher),
highlightOnHover: fallbackIfUndefined(true)
.....
where fallbackIfUndefined
is a computed macro:
import { computed } from '@ember/object';
export default function computedFallbackIfUndefined(fallback) {
return computed({
get() {
return fallback;
},
set(_, v) {
return v === undefined ? fallback : v;
}
});
}
This is a good convention for your team to follow.
In general, I would recommend first determining if the component is created in house or is a community created addon. If the latter, most popular ones provide documentation and follow good conventions within their source code. You can figure out if it's in house by looking in the components
directory for the component (assuming non pods layout).
If created in house, you're more or less on the right track. If your team writes tests, that should be an excellent repository of the component's capabilities! This approach is the secret sauce for understanding projects quickly across domains IMO.
I'm not sure why you would need to understand "all" options, though. When I use components that other team members have created, I regex search for their usages in templates and compare this specific UI / UX (actually by looking in the browser) to the behavior that I need to implement. You should only need to dig when you need different behavior from existing behavior in the app. It may help you to get more familiar with the product so you can better know what's available :)
Upvotes: 2