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:
Ajit Singh 2020-06-14 14:23:19 +05:30 committed by atscott
parent 209a18c624
commit 806d7aa22c
2 changed files with 57 additions and 21 deletions

View File

@ -1,7 +1,7 @@
<!-- #docregion v2, -->
<h1>My First Attribute Directive</h1>
<h4>Pick a highlight color</h4>
<h2>Pick a highlight color</h2>
<div>
<input type="radio" name="colors" (click)="color='lightgreen'">Green
<input type="radio" name="colors" (click)="color='yellow'">Yellow
@ -17,8 +17,22 @@
</p>
<!-- #enddocregion defaultColor, -->
<hr>
<p><i>Mouse over the following lines to see fixed highlights</i></p>
<hr />
<h2>Mouse over the following lines to see fixed highlights</h2>
<p [appHighlight]="'yellow'">Highlighted in yellow</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 -->

View File

@ -195,12 +195,12 @@ Add a `highlightColor` property to the directive class like this:
{@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.
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:
@ -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.
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>
@ -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>
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.
@ -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">
</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
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.
* [Respond to **events**](guide/attribute-directives#respond-to-user) that change the directive's behavior.
* [**Bind** values to the directive](guide/attribute-directives#bindings).
* [Prevent expression evaluation](guide/attribute-directives#ngNonBindable).
The final source code follows:
@ -337,9 +359,9 @@ You can also experience and download the <live-example title="Attribute Directiv
{@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:
<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>
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.
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?
The difference is a matter of trust.
Angular treats a component's template as _belonging_ to the component.
The component and its template trust each other implicitly.
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.
The properties of a component or directive are hidden from binding by default.
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.
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 (=),
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 (=),
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:
@ -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 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`,
not a property of the template's component. There are trust issues.
Therefore, the directive property must carry the `@Input` decorator.
not a property of the template's component.
For security, the directive property must carry the `@Input()` decorator.