docs: add documentation for ngNonBindable (#36560)
ngNonBindable documentation was not present, on docs site added documentation for ngNonBindable. With this template primitive, Angular won't evaluate expressions in elements. Fixes #28577 Fixes #19497 PR Close #36560
This commit is contained in:
parent
209a18c624
commit
806d7aa22c
|
@ -1,7 +1,7 @@
|
||||||
<!-- #docregion v2, -->
|
<!-- #docregion v2, -->
|
||||||
<h1>My First Attribute Directive</h1>
|
<h1>My First Attribute Directive</h1>
|
||||||
|
|
||||||
<h4>Pick a highlight color</h4>
|
<h2>Pick a highlight color</h2>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" name="colors" (click)="color='lightgreen'">Green
|
<input type="radio" name="colors" (click)="color='lightgreen'">Green
|
||||||
<input type="radio" name="colors" (click)="color='yellow'">Yellow
|
<input type="radio" name="colors" (click)="color='yellow'">Yellow
|
||||||
|
@ -17,8 +17,22 @@
|
||||||
</p>
|
</p>
|
||||||
<!-- #enddocregion defaultColor, -->
|
<!-- #enddocregion defaultColor, -->
|
||||||
|
|
||||||
<hr>
|
<hr />
|
||||||
<p><i>Mouse over the following lines to see fixed highlights</i></p>
|
<h2>Mouse over the following lines to see fixed highlights</h2>
|
||||||
|
|
||||||
<p [appHighlight]="'yellow'">Highlighted in yellow</p>
|
<p [appHighlight]="'yellow'">Highlighted in yellow</p>
|
||||||
<p appHighlight="orange">Highlighted in orange</p>
|
<p appHighlight="orange">Highlighted in orange</p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<h2>ngNonBindable</h2>
|
||||||
|
<!-- #docregion ngNonBindable -->
|
||||||
|
<p>Use ngNonBindable to stop evaluation.</p>
|
||||||
|
<p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p>
|
||||||
|
<!-- #enddocregion ngNonBindable -->
|
||||||
|
|
||||||
|
<!-- #docregion ngNonBindable-with-directive -->
|
||||||
|
<h3>ngNonBindable with a directive</h3>
|
||||||
|
<div ngNonBindable [appHighlight]="'yellow'">This should not evaluate: {{ 1 +1 }}, but will highlight yellow.
|
||||||
|
</div>
|
||||||
|
<!-- #enddocregion ngNonBindable-with-directive -->
|
||||||
|
|
|
@ -195,12 +195,12 @@ Add a `highlightColor` property to the directive class like this:
|
||||||
|
|
||||||
{@a input}
|
{@a input}
|
||||||
|
|
||||||
### Binding to an _@Input_ property
|
### Binding to an `@Input()` property
|
||||||
|
|
||||||
Notice the `@Input` decorator. It adds metadata to the class that makes the directive's `highlightColor` property available for binding.
|
Notice the `@Input()` decorator. It adds metadata to the class that makes the directive's `highlightColor` property available for binding.
|
||||||
|
|
||||||
It's called an *input* property because data flows from the binding expression _into_ the directive.
|
It's called an *input* property because data flows from the binding expression _into_ the directive.
|
||||||
Without that input metadata, Angular rejects the binding; see [below](guide/attribute-directives#why-input "Why add @Input?") for more about that.
|
Without that `@Input()` metadata, Angular rejects the binding; see [below](guide/attribute-directives#why-input "Why add @Input?") for more information.
|
||||||
|
|
||||||
Try it by adding the following directive binding variations to the `AppComponent` template:
|
Try it by adding the following directive binding variations to the `AppComponent` template:
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ This is disagreeable. The word, `appHighlight`, is a terrible property name and
|
||||||
|
|
||||||
Fortunately you can name the directive property whatever you want _and_ **_alias it_** for binding purposes.
|
Fortunately you can name the directive property whatever you want _and_ **_alias it_** for binding purposes.
|
||||||
|
|
||||||
Restore the original property name and specify the selector as the alias in the argument to `@Input`.
|
Restore the original property name and specify the selector as the alias in the argument to `@Input()`.
|
||||||
|
|
||||||
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (color property with alias)" region="color"></code-example>
|
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (color property with alias)" region="color"></code-example>
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ and fall back to "violet" as the default color.
|
||||||
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
|
<code-example path="attribute-directives/src/app/app.component.html" header="src/app/app.component.html (defaultColor)" region="defaultColor"></code-example>
|
||||||
|
|
||||||
Angular knows that the `defaultColor` binding belongs to the `HighlightDirective`
|
Angular knows that the `defaultColor` binding belongs to the `HighlightDirective`
|
||||||
because you made it _public_ with the `@Input` decorator.
|
because you made it _public_ with the `@Input()` decorator.
|
||||||
|
|
||||||
Here's how the harness should work when you're done coding.
|
Here's how the harness should work when you're done coding.
|
||||||
|
|
||||||
|
@ -311,6 +311,27 @@ Here's how the harness should work when you're done coding.
|
||||||
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
|
<img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
{@a ngNonBindable}
|
||||||
|
|
||||||
|
## `ngNonBindable`
|
||||||
|
|
||||||
|
With the built-in template primitive `ngNonBindable`, Angular won't
|
||||||
|
evaluate expressions in elements. For example:
|
||||||
|
|
||||||
|
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html" region="ngNonBindable"></code-example>
|
||||||
|
|
||||||
|
The expression `{{ 1 + 1 }}` will render just as it does in your code editor,
|
||||||
|
and will not display `2`. This is helpful when you want to render code in the browser.
|
||||||
|
|
||||||
|
When you apply `ngNonBindable` to an element, it stops any binding starting at that element, including child elements. However, `ngNonBindable` still allows
|
||||||
|
directives to work to the element where you apply `ngNonBindable`. In the following example, the `appHighlight` directive will still be active but Angular will not evaluate the expression `{{ 1 + 1 }}`.
|
||||||
|
|
||||||
|
<code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html" region="ngNonBindable-with-directive"></code-example>
|
||||||
|
|
||||||
|
Additionally, if you apply `ngNonBindable` to a parent element, interpolation and binding of any sort, such as property binding, or event binding, is disabled for its children.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
|
|
||||||
This page covered how to:
|
This page covered how to:
|
||||||
|
@ -319,6 +340,7 @@ This page covered how to:
|
||||||
* [Apply the directive](guide/attribute-directives#apply-directive) to an element in a template.
|
* [Apply the directive](guide/attribute-directives#apply-directive) to an element in a template.
|
||||||
* [Respond to **events**](guide/attribute-directives#respond-to-user) that change the directive's behavior.
|
* [Respond to **events**](guide/attribute-directives#respond-to-user) that change the directive's behavior.
|
||||||
* [**Bind** values to the directive](guide/attribute-directives#bindings).
|
* [**Bind** values to the directive](guide/attribute-directives#bindings).
|
||||||
|
* [Prevent expression evaluation](guide/attribute-directives#ngNonBindable).
|
||||||
|
|
||||||
The final source code follows:
|
The final source code follows:
|
||||||
|
|
||||||
|
@ -337,9 +359,9 @@ You can also experience and download the <live-example title="Attribute Directiv
|
||||||
|
|
||||||
{@a why-input}
|
{@a why-input}
|
||||||
|
|
||||||
### Appendix: Why add _@Input_?
|
### Appendix: Why add `@Input()`?
|
||||||
|
|
||||||
In this demo, the `highlightColor` property is an ***input*** property of
|
In this demo, the `highlightColor` property is an `@Input()` property of
|
||||||
the `HighlightDirective`. You've seen it applied without an alias:
|
the `HighlightDirective`. You've seen it applied without an alias:
|
||||||
|
|
||||||
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
|
<code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
|
||||||
|
@ -348,33 +370,33 @@ You've seen it with an alias:
|
||||||
|
|
||||||
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
|
<code-example path="attribute-directives/src/app/highlight.directive.ts" header="src/app/highlight.directive.ts (color)" region="color"></code-example>
|
||||||
|
|
||||||
Either way, the `@Input` decorator tells Angular that this property is
|
Either way, the `@Input()` decorator tells Angular that this property is
|
||||||
_public_ and available for binding by a parent component.
|
_public_ and available for binding by a parent component.
|
||||||
Without `@Input`, Angular refuses to bind to the property.
|
Without `@Input()`, Angular refuses to bind to the property.
|
||||||
|
|
||||||
You've bound template HTML to component properties before and never used `@Input`.
|
You've bound template HTML to component properties before and never used `@Input()`.
|
||||||
What's different?
|
What's different?
|
||||||
|
|
||||||
The difference is a matter of trust.
|
The difference is a matter of trust.
|
||||||
Angular treats a component's template as _belonging_ to the component.
|
Angular treats a component's template as _belonging_ to the component.
|
||||||
The component and its template trust each other implicitly.
|
The component and its template trust each other implicitly.
|
||||||
Therefore, the component's own template may bind to _any_ property of that component,
|
Therefore, the component's own template may bind to _any_ property of that component,
|
||||||
with or without the `@Input` decorator.
|
with or without the `@Input()` decorator.
|
||||||
|
|
||||||
But a component or directive shouldn't blindly trust _other_ components and directives.
|
But a component or directive shouldn't blindly trust _other_ components and directives.
|
||||||
The properties of a component or directive are hidden from binding by default.
|
The properties of a component or directive are hidden from binding by default.
|
||||||
They are _private_ from an Angular binding perspective.
|
They are _private_ from an Angular binding perspective.
|
||||||
When adorned with the `@Input` decorator, the property becomes _public_ from an Angular binding perspective.
|
When adorned with the `@Input()` decorator, the property becomes _public_ from an Angular binding perspective.
|
||||||
Only then can it be bound by some other component or directive.
|
Only then can it be bound by some other component or directive.
|
||||||
|
|
||||||
You can tell if `@Input` is needed by the position of the property name in a binding.
|
You can tell if `@Input()` is needed by the position of the property name in a binding.
|
||||||
|
|
||||||
* When it appears in the template expression to the ***right*** of the equals (=),
|
* When it appears in the template expression to the ***right*** of the equals (=),
|
||||||
it belongs to the template's component and does not require the `@Input` decorator.
|
it belongs to the template's component and does not require the `@Input()` decorator.
|
||||||
|
|
||||||
* When it appears in **square brackets** ([ ]) to the **left** of the equals (=),
|
* When it appears in **square brackets** ([ ]) to the **left** of the equals (=),
|
||||||
the property belongs to some _other_ component or directive;
|
the property belongs to some _other_ component or directive;
|
||||||
that property must be adorned with the `@Input` decorator.
|
that property must be adorned with the `@Input()` decorator.
|
||||||
|
|
||||||
Now apply that reasoning to the following example:
|
Now apply that reasoning to the following example:
|
||||||
|
|
||||||
|
@ -382,8 +404,8 @@ Now apply that reasoning to the following example:
|
||||||
|
|
||||||
* The `color` property in the expression on the right belongs to the template's component.
|
* The `color` property in the expression on the right belongs to the template's component.
|
||||||
The template and its component trust each other.
|
The template and its component trust each other.
|
||||||
The `color` property doesn't require the `@Input` decorator.
|
The `color` property doesn't require the `@Input()` decorator.
|
||||||
|
|
||||||
* The `appHighlight` property on the left refers to an _aliased_ property of the `HighlightDirective`,
|
* The `appHighlight` property on the left refers to an _aliased_ property of the `HighlightDirective`,
|
||||||
not a property of the template's component. There are trust issues.
|
not a property of the template's component.
|
||||||
Therefore, the directive property must carry the `@Input` decorator.
|
For security, the directive property must carry the `@Input()` decorator.
|
||||||
|
|
Loading…
Reference in New Issue