-
Notifications
You must be signed in to change notification settings - Fork 875
example(template-syntax): follow style-guide and other updates #2750
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -305,10 +305,10 @@ <h3> | |
|
||
<div> | ||
<!-- #docregion event-binding-3 --> | ||
<!-- `myClick` is an event on the custom `MyClickDirective` --> | ||
<!-- #docregion my-click --> | ||
<!-- `myClick` is an event on the custom `ClickDirective` --> | ||
<!-- #docregion myClick --> | ||
<div (myClick)="clickMessage=$event">click with myClick</div> | ||
<!-- #enddocregion my-click --> | ||
<!-- #enddocregion myClick --> | ||
<!-- #enddocregion event-binding-3 --> | ||
{{clickMessage}} | ||
</div> | ||
|
@@ -351,21 +351,22 @@ <h3> | |
<hr><h2 id="two-way">Two-way Binding</h2> | ||
<div id="two-way-1"> | ||
<!-- #docregion two-way-1 --> | ||
<my-sizer [(size)]="fontSize"></my-sizer> | ||
<div [style.font-size.px]="fontSize">Resizable Text</div> | ||
<my-sizer [(size)]="fontSizePx"></my-sizer> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change seems picayune. I feel it distracts from the point and starts a conversation that isn't helpful. I can understand that you feel that being inspecific about the units in the property name provokes a distracting conversation too. I don't actually feel strongly about this so I'd say "whatever, OK" . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, this is mainly to avoid a conflict with a string property named It seemed to me that since the property is being assigned to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm cool with it |
||
<div [style.font-size.px]="fontSizePx">Resizable Text</div> | ||
<!-- #enddocregion two-way-1 --> | ||
<label>FontSize: <input id="fontsize" [(ngModel)]="fontSize"></label> | ||
<label>FontSize (px): <input [(ngModel)]="fontSizePx"></label> | ||
</div> | ||
<br> | ||
<div id="two-way-2"> | ||
<h3>De-sugared two-way binding</h3> | ||
<!-- #docregion two-way-2 --> | ||
<my-sizer [size]="fontSize" (sizeChange)="fontSize=$event"></my-sizer> | ||
<my-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></my-sizer> | ||
<!-- #enddocregion two-way-2 --> | ||
</div> | ||
<br><br> | ||
|
||
<a class="to-toc" href="#toc">top</a> | ||
|
||
<!-- Two way data binding unwound; | ||
passing the changed display value to the event handler via `$event` --> | ||
<hr><h2 id="ngModel">NgModel (two-way) Binding</h2> | ||
|
@@ -428,6 +429,18 @@ <h3>Result: {{currentHero.firstName}}</h3> | |
<!-- NgStyle binding --> | ||
<hr><h2 id="ngStyle">NgStyle Binding</h2> | ||
|
||
<!-- #docregion NgStyle --> | ||
<div> | ||
<p [ngStyle]="setStyle()" #styleP>Change style of this text!</p> | ||
|
||
<label>Italic: <input type="checkbox" [(ngModel)]="isItalic"></label> | | ||
<label>Bold: <input type="checkbox" [(ngModel)]="isBold"></label> | | ||
<label>Size: <input type="text" [(ngModel)]="fontSize"></label> | ||
|
||
<p>Style set to: <code>'{{styleP.style.cssText}}'</code></p> | ||
</div> | ||
<!-- #enddocregion NgStyle --> | ||
|
||
<!-- #docregion NgStyle-1 --> | ||
<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" > | ||
This div is x-large. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -490,8 +490,8 @@ table | |
If we must read a target element property or call one of its methods, | ||
we'll need a different technique. | ||
See the API reference for | ||
[viewChild](../api/core/index/ViewChild-decorator.html) and | ||
[contentChild](../api/core/index/ContentChild-decorator.html). | ||
[ViewChild](../api/core/index/ViewChild-decorator.html) and | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
[ContentChild](../api/core/index/ContentChild-decorator.html). | ||
|
||
:marked | ||
### Binding target | ||
|
@@ -581,7 +581,7 @@ a(id="one-time-initialization") | |
|
||
|
||
:marked | ||
#### Content Security | ||
#### Content security | ||
Imagine the following *malicious content*. | ||
+makeExample('template-syntax/ts/app/app.component.ts', 'evil-title')(format=".") | ||
:marked | ||
|
@@ -599,10 +599,10 @@ figure.image-display | |
.l-main-section | ||
:marked | ||
<a id="other-bindings"></a> | ||
## Attribute, Class, and Style Bindings | ||
## Attribute, class, and style bindings | ||
The template syntax provides specialized one-way bindings for scenarios less well suited to property binding. | ||
|
||
### Attribute Binding | ||
### Attribute binding | ||
We can set the value of an attribute directly with an **attribute binding**. | ||
.l-sub-section | ||
:marked | ||
|
@@ -652,7 +652,7 @@ code-example(format="nocode"). | |
is to set ARIA attributes, as in this example: | ||
+makeExample('template-syntax/ts/app/app.component.html', 'attrib-binding-aria')(format=".") | ||
:marked | ||
### Class Binding | ||
### Class binding | ||
|
||
We can add and remove CSS class names from an element’s `class` attribute with | ||
a **class binding**. | ||
|
@@ -668,9 +668,6 @@ code-example(format="nocode"). | |
We can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding. | ||
+makeExample('template-syntax/ts/app/app.component.html', 'class-binding-2')(format=".") | ||
|
||
block dart-class-binding-bug | ||
//- N/A | ||
|
||
:marked | ||
Finally, we can bind to a specific class name. | ||
Angular adds the class when the template expression evaluates to #{_truthy}. | ||
|
@@ -683,7 +680,7 @@ block dart-class-binding-bug | |
we generally prefer the [NgClass directive](#ngClass) for managing multiple class names at the same time. | ||
|
||
:marked | ||
### Style Binding | ||
### Style binding | ||
|
||
We can set inline styles with a **style binding**. | ||
|
||
|
@@ -747,7 +744,7 @@ block style-property-name-dart-diff | |
on [aliasing input/output properties](#aliasing-io). | ||
|
||
:marked | ||
If the name fails to match element event or output property of a known directive, | ||
If the name fails to match an element event or an output property of a known directive, | ||
Angular reports an “unknown directive” error. | ||
|
||
### *$event* and event handling statements | ||
|
@@ -778,7 +775,7 @@ block style-property-name-dart-diff | |
|
||
<a id="eventemitter"></a> | ||
<a id="custom-event"></a> | ||
### Custom Events with EventEmitter | ||
### Custom events with *EventEmitter* | ||
|
||
Directives typically raise custom events with an Angular [EventEmitter](../api/core/index/EventEmitter-class.html). | ||
The directive creates an `EventEmitter` and exposes it as a property. | ||
|
@@ -853,36 +850,44 @@ block style-property-name-dart-diff | |
|
||
Angular offers a special _two-way data binding_ syntax for this purpose, **`[(x)]`**. | ||
The `[(x)]` syntax combines the brackets | ||
of _Property Binding_, `[x]`, with the parentheses of _Event Binding_, `(x)`. | ||
of _property binding_, `[x]`, with the parentheses of _event binding_, `(x)`. | ||
|
||
.callout.is-important | ||
header [( )] = banana in a box | ||
:marked | ||
Visualize a *banana in a box* to remember that the parentheses go _inside_ the brackets. | ||
|
||
:marked | ||
The `[(x)]` syntax is easy to demonstrate when the element has a settable property called `x` | ||
and a corresponding event named `xChange`. | ||
Here's a `SizerComponent` that fits the pattern. | ||
It has a `size` value property and a companion `sizeChange` event: | ||
+makeExample('template-syntax/ts/app/sizer.component.ts', null, 'app/sizer.component.ts') | ||
|
||
+makeExample('app/sizer.component.ts') | ||
|
||
:marked | ||
The initial `size` is an input value from a property binding. | ||
Clicking the buttons increases or decreases the `size`, within min/max values constraints, | ||
and then raises (_emits_) the `sizeChange` event with the adjusted size. | ||
|
||
Here's an example in which the `AppComponent.fontSize` is two-way bound to the `SizerComponent`: | ||
+makeExample('template-syntax/ts/app/app.component.html', 'two-way-1')(format=".") | ||
Here's an example in which the `AppComponent.fontSizePx` is two-way bound to the `SizerComponent`: | ||
|
||
+makeExcerpt('app/app.component.html', 'two-way-1', '') | ||
|
||
:marked | ||
The `AppComponent.fontSize` establishes the initial `SizerComponent.size` value. | ||
Clicking the buttons updates the `AppComponent.fontSize` via the two-way binding. | ||
The revised `AppComponent.fontSize` value flows through to the _style_ binding, making the displayed text bigger or smaller. | ||
Try it in the <live-example>live example</live-example>. | ||
The `AppComponent.fontSizePx` establishes the initial `SizerComponent.size` value. | ||
Clicking the buttons updates the `AppComponent.fontSizePx` via the two-way binding. | ||
The revised `AppComponent.fontSizePx` value flows through to the _style_ binding, making the displayed text bigger or smaller. | ||
Try it in the <live-example></live-example>. | ||
|
||
The two-way binding syntax is really just syntactic sugar for a _property_ binding and an _event_ binding. | ||
Angular _desugars_ the `SizerComponent` binding into this: | ||
+makeExample('template-syntax/ts/app/app.component.html', 'two-way-2')(format=".") | ||
|
||
+makeExcerpt('app/app.component.html', 'two-way-2', '') | ||
|
||
:marked | ||
The `$event` variable contains the payload of the `SizerComponent.sizeChange` event. | ||
Angular assigns the `$event` value to the `AppComponent.fontSize` when the user clicks the buttons. | ||
Angular assigns the `$event` value to the `AppComponent.fontSizePx` when the user clicks the buttons. | ||
|
||
Clearly the two-way binding syntax is a great convenience compared to separate property and event bindings. | ||
|
||
|
@@ -1418,7 +1423,7 @@ h3#aliasing-io Aliasing input/output properties | |
Directive consumers expect to bind to the name of the directive. | ||
For example, when we apply a directive with a `myClick` selector to a `<div>` tag, | ||
we expect to bind to an event property that is also called `myClick`. | ||
+makeExample('template-syntax/ts/app/app.component.html', 'my-click')(format=".") | ||
+makeExample('template-syntax/ts/app/app.component.html', 'myClick')(format=".") | ||
:marked | ||
However, the directive name is often a poor choice for the name of a property within the directive class. | ||
The directive name rarely describes what the property does. | ||
|
@@ -1431,14 +1436,14 @@ h3#aliasing-io Aliasing input/output properties | |
|
||
We can specify the alias for the property name by passing it into the input/output decorator like this: | ||
|
||
+makeExample('template-syntax/ts/app/my-click.directive.ts', 'my-click-output-1')(format=".") | ||
+makeExample('template-syntax/ts/app/click.directive.ts', 'output-myClick')(format=".") | ||
|
||
.l-sub-section | ||
:marked | ||
We can also alias property names in the `inputs` and `outputs` #{_array}s. | ||
We write a colon-delimited (`:`) string with | ||
the directive property name on the *left* and the public alias on the *right*: | ||
+makeExample('template-syntax/ts/app/my-click.directive.ts', 'my-click-output-2')(format=".") | ||
+makeExample('template-syntax/ts/app/click.directive.ts', 'output-myClick2')(format=".") | ||
|
||
<a id="expression-operators"></a> | ||
.l-main-section | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure that we don't have to wait for the browser to settle after clicking the button. That line had a purpose at one time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, e2e tests run fine: