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

Add deprecation guides for template transforms #778

Merged
merged 1 commit into from
Feb 2, 2021
Merged
Show file tree
Hide file tree
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
27 changes: 27 additions & 0 deletions content/ember/v3/attrs-arg-access.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
id: attrs-arg-access
title: "Accessing named args via {{attrs}}"
until: '4.0.0'
since: 'Upcoming Features'
---

The `{{attrs}}` object was an alternative way to reference named arguments in
templates that was introduced prior to named arguments syntax being finalized.
References to properties on `{{attrs}}` can be converted directly to named
argument syntax.

Before:

```hbs
{{attrs.foo}}
{{this.attrs.foo.bar}}
{{deeply (nested attrs.foobar.baz)}}
```

After:

```hbs
{{@foo}}
{{@foo.bar}}
{{deeply (nested @foobar.baz)}}
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
id: class-binding-and-class-name-bindings-in-templates
title: "classBinding and classNameBindings as args in templates"
until: '4.0.0'
since: 'Upcoming Features'
---

`classBinding` and `classNameBindings` can currently be passed as arguments to
components that are invoked with curly invocation. These allow users to
conditionally bind values to the `class` argument using a microsyntax similar to
the one that can be defined in a Classic component's class body:

```js
import Component from '@ember/component';

export default Component.extend({
classNameBindings: ['isValid:is-valid:is-invalid']
});
```

```hbs
{{my-component classNameBindings="isValid:is-valid:is-invalid"}}
```

Each binding is a triplet separated by colons. The first identifier in the
triplet is the value that the class name should be bound to, the second
identifier is the name of the class to add if the bound value is truthy, and the
third value is the name to bind if the value is falsy.

These bindings are additive - they add to the existing bindings that are on the
class, rather than replacing them. Multiple bindings can also be passed in by
separating them with a space:

```hbs
{{my-component
classBinding="foo:bar"
classNameBindings="some.boundProperty isValid:is-valid:is-invalid"
}}
```


These bindings can be converted into passing a concatenated string into the
class argument of the component, using inline `if` to reproduce the same
behavior. This is most conveniently done by converting the component to use
angle-bracket invocation at the same time.

Before:

```hbs
{{my-component
classBinding="foo:bar"
classNameBindings="some.boundProperty isValid:is-valid:is-invalid"
}}
```

After:

```hbs
<MyComponent
class="
{{if this.foo "bar"}}
{{if this.some.boundProperty "bound-property"}}
{{if this.isValid "is-valid" "is-invalid"}}
"
>
```

Note that we are passing in the `class` attribute, not the `class` argument. In
most cases, this should work exactly the same as previously. If you referenced
the `class` argument inside of your component, however, you will need to pass
`@class` instead.

If you do not want to convert to angle bracket syntax for some reason, the same
thing can be accomplished with the `(concat)` helper in curly invocation.

```hbs
{{my-component
class=(concat
(if this.foo "bar")
" "
(if this.some.boundProperty "bound-property")
" "
(if this.isValid "is-valid" "is-invalid")
)
}}
```
72 changes: 72 additions & 0 deletions content/ember/v3/has-block-and-has-block-params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
id: has-block-and-has-block-params
title: "{{hasBlock}} and {{hasBlockParams}}"
until: '4.0.0'
since: 'Upcoming Features'
---

#### `{{hasBlock}}`

The `{{hasBlock}}` property is true if the component was given a default block,
and false otherwise. To transition away from it, you can use the `(has-block)`
helper instead.

```hbs
{{hasBlock}}

{{! becomes }}
{{has-block}}
```

Unlike `{{hasBlock}}`, the `(has-block)` helper must be called, so in nested
positions you will need to add parentheses around it:

```hbs
{{#if hasBlock}}

{{/if}}


{{! becomes }}
{{#if (has-block)}}

{{/if}}
```

You may optionally pass a name to `(has-block)`, the name of the block to check.
The name corresponding to the block that `{{hasBlock}}` represents is "default".
Calling `(has-block)` without any arguments is equivalent to calling
`(has-block "default")`.

#### `{{hasBlockParams}}`

The `{{hasBlockParams}}` property is true if the component was given a default block
that accepts block params, and false otherwise. To transition away from it, you can
use the `(has-block-params)` helper instead.

```hbs
{{hasBlockParams}}

{{! becomes }}
{{has-block-params}}
```

Unlike `{{hasBlockParams}}`, the `(has-block-params)` helper must be called, so in nested
positions you will need to add parentheses around it:

```hbs
{{#if hasBlockParams}}

{{/if}}


{{! becomes }}
{{#if (has-block-params)}}

{{/if}}
```

You may optionally pass a name to `(has-block-params)`, the name of the block to check.
The name corresponding to the block that `{{hasBlockParams}}` represents is "default".
Calling `(has-block-params)` without any arguments is equivalent to calling
`(has-block-params "default")`.