简体   繁体   中英

What is the Ember Octane replacement for `didInsertElement`?

I'm trying to fire a callback passed down from a parent component. Our old pattern for handling this was to call the function in didInsertElement. In Octane, I see that we can use the did-insert modifier but that seems weird for this use case since we're not updating the DOM element that we'd use to call did-insert. I've also seen onRender being used in a few cases but I don't see documentation on that and it's not firing for me. Any suggestions?

For this specific use case, we have a parent component that can have one of many child components. And for each child component we have specific text that gets displayed in the parent component and we want the child component to be the owner of that text.

Your instinct that did-insert isn't the right solution here is, I think, correct. In general, modifiers should only be used when the element they're going to be attached to is used in some way—that is, for managing interactions with the DOM. In general, we prefer one-way data flow otherwise. However, the scenario you've outlined looks similar to a "registration" pattern, where when a child is instantiated, it tells its parent "Hey, I'm here, here's the info you need about me."

There are a couple reasonable options in this case:

  1. Rethink whether the child component should in fact own that data. I don't doubt you have a good reason for the child component owning the data, but the fact that the parent is already responsible for deciding which child to render may suggest that a mapping which includes both the component to render and the associated text could be a good solution in this space. That would cleanly solve this issue.

  2. Given that per your description you currently do want to avoid having the parent own that data, you could also consider having the child yield the data. However, this usually only works if the DOM relationship for it makes sense. If it does, you could choose to do something like this:

     {{yield (hash block='data' text=this.theText)}} <div class='the-component-body'> {{yield}} </div>
     <ChildComponent as |child|> {{#if (eq child.block 'data'}} <h2>{{child.text}}</h2> {{/if}} {{child}} </Child>

    (You can see this strategy working here —in particular, see the resulting DOM!)

    While that's very powerful, again, it only works if your DOM layout supports it.

  3. Finally, and perhaps most simply for the use case you have, you can (though not necessarily best , as I think the other options above are usually better when available), you can 'register' the value for the component by calling an action passed into your component during the constructor . Now, using a component's constructor this way for component behavior can be a problem in that it only runs once, when the component is first instantiated, and Glimmer and Ember keep the component instance stable and just change the values passed to them over time as much as possible, so if the value you're passing back up depends on the argument you pass to it, the constructor won't work. If it's always stable and does not depend on the arguments to a component, this does work, and it's often appropriate for a 'registration' pattern, where the child component simply needs to pass a single piece of data to the parent when instantiated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM