How to reference an HTML element for a composed view

I cannot get a reference to an HTML element in the “attached” lifecycle event for a view model whose view contains a composed view (without a view model).

I am migrating a Durandal application to Aurelia. Aurelia does not fire a compositionComplete lifecycle event like Durandal. The last event in the Aurelia lifecycle is “attached”.

I have created a Durandal dFiddle that demonstrates that the view model compositionComplete lifecycle event can reference the composed view HTML element. The Durandal “attached” event cannot reference the composed view HTML element.
https://ericedgar.github.io/dFiddle-2.0/#hello/dFiddle

I have created an Aurelia CodeSandbox project that demonstrates that an HTML element from a composed view (without a view model) cannot be accessed in the “attached” event of the view model of the view that contains the composed view (without a view model). Refreshing will sometimes find the composed view HTML element 200 milliseconds after the form “attached” event fires.
https://codesandbox.io/s/3wxx3xrw5

How do I get a reference to an HTML element in a composed view without using a setTimeout in the “attached” event?

1 Like

From the source code of compose https://github.com/aurelia/templating-resources/blob/master/src/compose.js , it’s clear that there is no composition complete event being fired. It would be nice if you could PR to add this feature. Also poking @EisenbergEffect for some thoughts.

1 Like

Interesting. Well, one bit of good news is that we’ve already solved this issue in vNext :slight_smile: Obviously, that doesn’t help you right now, so let’s see what we could do. setTimeout isn’t the best solution but at least it gets you past the issue. Have you tried using the micro task queue? That would be slightly better, though still a work around. I’d definitely take a PR to add the composition complete event. One thing I’d want to note is that we’d remove that as no longer necessary in vNext I think. @ericedgar Any interest in working with us on a contribution for that?

1 Like

I almost posted a similar question last Thursday but I found a solution:. Adding the <require> tag for the view that you are going to compose seems to allow the composition engine to render the view without a view model before the attached callback is fired:

  <require from="./[your_view].html"></require>
  <compose view="./[your_view].html"></compose>

With @ericedgar’s example this works: https://codesandbox.io/s/61o8qrnrzz. But I am not sure this would work with a dynamic view path.

2 Likes

Thanks for the reply, I’ll take a look at the micro task queue. Yes, I have interest in working with the team on future contributions. It appears @gooeyideas example of using the require element in the markup will allow the composed view element to be accessed in the attached event. So my problem is solved. For now, adding a compositionComplete event won’t be necessary, especially since there is a solution in vNext :+1:

Thanks @gooeyideas, the require element in the markup will allow the composed view element to be accessed in the attached event. My problem is solved! :grinning:

One thing to note, if the composed view is inside an HTML element with an if.bind, then the element still cannot be accessed in the attached event. Once I changed the if.bind to a show.bind, then all is good again.

Thanks for the follow up @ericedgar! And whenever you feel like getting involved, we welcome your feedback on vNext work. Best wishes!

1 Like