Hello, good morning everyone
I want to ask what are the best practices of declaring bindings in views with several components / containers in Perspective.
As I find messy to keep track of all my bindings and then use the result in a sibling, parent or child container, I have been declaring the important ones on the root container.
I am not sure if declaring them on the root container is the best way to do it or if affects performance but I find it way easier to manipulate them there rather than going deep into all my components
Here is an example of one of my views (Any comment is more than welcome this is the messy result of a user changing the requirements like 50 times hehe) :
For example:
- The variable named "XYChart" goes directly to the dataSources props of that component and is also used in the percentage bar at the bottom.
- The variables from the Dropdown dictionary goes to the options props of the dropdowns at the top.
1 Like
I learned early on in Perspective to keep almost all property/bindings on the top level component. The only bindings I use on other components are usually dirt-simple direct bindings without transforms.
This also applies if some component is collecting input from the user. I usually do a bidirectional binding of that input back to a property on the top level component. The big reason is that if you ever need to reorganize or visually rearrange the view, you don't have to spend forever chasing down parent/sibling references in other places. If you move an input component to a different place visually, it still pushes to the same top level property that the consumers depend on, and you don't need to change anything else.
I also tend to keep most message handlers and custom methods attached to the root component for very similar reasons. It's easier to only have to look in one place, and references to them will never need to change parent/sibling naming paths. It's usually self.view.getChild("root").myMethod()
...
6 Likes
And there's no performance implication for where you store custom properties.
3 Likes
This was exactly the reason why I started to declare custom properties on the root container / parent container. It was really annoying to update the reference of a property (usually just had to add a miserable "." ) when I changed the location or name of a component.
Thank you for sharing!
Don't forget that you have the option of moving them out even further to the session.custom
properties to make them available to all pages in a project. This is very hand for all sorts of things that have to be shared between pages or to avoid running duplicate tag queries, for example, on multiple pages or views.
6 Likes
I'd nuance that a bit: while I don't like digging through components to find bindings, I also don't like having things out of their scope.
So I try to find a balance and maybe put some bindings that concern foo
on a foo
container, those that concern bar
on a bar
container, or directly on the component if they affect only a component - for example, I have tables with complex data building, so I put bindings and transforms in the table's custom properties.
As long as you don't have custom props at every level, and that the levels where they are make sense...
6 Likes
I had started to adopt this practice for the reasons stated above and it's good to see that approach validated here. I do have another question or two, though...
I have a table with its selection.data
property bound bi-directionally to a custom prop on the top level container, so other components can react to the data selected by the user. Another custom prop at the top level holds the dataset to which the table data is bound. I also want to have a flex repeater of 'shortcut' buttons elsewhere on the same view, where each shortcut button references a key value in the same dataset. When the shortcut button is clicked, I want the corresponding table row to be selected (and scrolled into view). On one hand, I figured I could use a bi-directional binding of the table's selection.selectedRow
property to a custom prop on the top level, then look up the key value in the dataset to get the row index and write that to the top-level prop. On the other hand, I considered writing a custom method - or perhaps message handler - on the table object that would take the key value and do the selecting and scrolling. Which of these is the better approach?
Secondly, is it better to have these top-level custom properties on the root container or on the view itself?
That's a good technique to centralize that selection information, but...
In all my testing, writing to selection.data
has no effect. Writing to selection.selectedRow
is the only way to deliberately select something, and there is no way to script any multi-row selection.
I'm not aware of any way to script a table scroll, either. (I'd like to be wrong about that.)
Definitely use view.custom
for top-level props. Offers the simplest possible usage in both expressions and scripts.
3 Likes