`
})
export class SizerComponent {
- @Input() size: number;
+ @Input() size: number | string;
@Output() sizeChange = new EventEmitter();
dec() { this.resize(-1); }
inc() { this.resize(+1); }
resize(delta: number) {
- const size = +this.size + delta;
- this.size = Math.min(40, Math.max(8, size));
+ this.size = Math.min(40, Math.max(8, +this.size + delta));
this.sizeChange.emit(this.size);
}
}
diff --git a/public/docs/ts/latest/guide/template-syntax.jade b/public/docs/ts/latest/guide/template-syntax.jade
index 9956bcf654..ef9ab05371 100644
--- a/public/docs/ts/latest/guide/template-syntax.jade
+++ b/public/docs/ts/latest/guide/template-syntax.jade
@@ -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
+ [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
- ## 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
- ### 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.
+ 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 .
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 `
` 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=".")
.l-main-section