Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update modifiers related sections to be accurate to what we've been able to do since 3.25 #1829

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 28 additions & 22 deletions guides/release/components/template-lifecycle-dom-and-modifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,45 +243,51 @@ On the other hand, if you're looking at JavaScript documentation that tells you

If you want to set a property, you can use the `prop` element modifier.

## Calling Methods On First Render
## Calling Methods On Render

So far, we've talked about web APIs that work by setting attributes as well as web APIs that work by setting properties. But what about web APIs that work by calling methods, like setting focus on an element?
So far, we've talked about web APIs that work by setting attributes as well as web APIs that work by setting properties. But what about web APIs that work by calling methods, like setting focus on an element?

For example, let's say we want to focus an `<input>` in a form as soon as the form is rendered. The web API for focusing an element is:

```js
inputElement.focus();
```

This code needs to run after the element is rendered.
We can use a modifier to run a method immediately after an element has rendered.
To follow along with the examples below, make sure you have `ember-modifier` installed in your app:

The simplest way to accomplish this is by using the `did-insert` modifier from [@ember/render-modifiers][render-modifiers].

[render-modifiers]: https://github.com/emberjs/ember-render-modifiers

```handlebars {app/components/edit-form.hbs}
<form>
<input {{did-insert this.focus}}>
</form>
```
ember install ember-modifier
```

Import `modifier` from `ember-modfier`, add an `autofocus` method to the component class,
and then use it in a component template.

```js {app/components/edit-form.js}
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { modifier } from 'ember-modifier';

export default class EditFormComponent extends Component {
@action
focus(element) {
element.focus();
}
autofocus = modifier((element) => element.focus(), { eager: false });
}
```

The `did-insert` modifier will call a function after its element is added to the DOM. That function receives the element as a parameter.
Here is how we can use our new modifier in a template:

```handlebars {app/components/edit-form.hbs}
<form>
<label>
Name:
<input {{this.autofocus}}>
<label>
</form>
```

Modifiers can be used in many other ways! For API documentation and more examples, visit the [the `ember-modifier` README](https://github.com/ember-modifier/ember-modifier).

### Abstracting the Logic Into a Custom Modifier
### Abstracting the Logic Into a Shareable Modifier

Using the `did-insert` modifier works well for one-off cases, but if you want to pull this logic into reusable functionality that you can use throughout your app, you can make your _own_ modifier.
Writing a modifier in a component class works well for one-time use cases, but if you want to reuse the modifier in other places within your app, you can move the modifier to a globally accessible place.

The modifier that we're going to build will allow us to say:

Expand All @@ -291,9 +297,9 @@ The modifier that we're going to build will allow us to say:
</form>
```

Pretty nice, right?
No need for `this`, or to define anything on your component class.

To accomplish that, we'll create a modifier in `app/modifiers/autofocus.js`. First, install [`ember-modifier`](https://github.com/ember-modifier/ember-modifier) and then generate an `autofocus` modifier for your app:
To accomplish that, we'll create a file at `app/modifiers/autofocus.js`. First, ensure that [`ember-modifier`](https://github.com/ember-modifier/ember-modifier) is installed and then generate an `autofocus` modifier for your app:

```bash
ember install ember-modifier
Expand Down Expand Up @@ -448,7 +454,7 @@ document.addEventListener("click", event => {

The most important difference between this example and the cases we've seen so far is that we need to remove the `click` event handler from the document when this element is destroyed.

To accomplish this, we can use [`ember-modifier`](https://github.com/ember-modifier/ember-modifier) to create a `on-click-outside` modifier that sets up the event listener after the element is first inserted and removes the event listener when the element is removed.
To accomplish this, we can use [`ember-modifier`](https://github.com/ember-modifier/ember-modifier) to create a `on-click-outside` modifier that sets up the event listener after the element is first inserted and removes the event listener when the element is removed.

Run the following commands to install the addon and generate a new modifier:

Expand Down