docs(template-syntax): Clarify input/output aliasing syntax

closes #722
This commit is contained in:
Ward Bell 2016-01-18 23:54:27 -08:00
parent fe5c605090
commit 034a5a6943
3 changed files with 36 additions and 27 deletions

View File

@ -257,10 +257,10 @@ button</button>
<!-- `myClick` is an event on the custom `MyClickDirective` --> <!-- `myClick` is an event on the custom `MyClickDirective` -->
<!-- #docregion my-click --> <!-- #docregion my-click -->
<div myClick (myClick)="clickity=$event">click with myClick</div> <div myClick (myClick)="clickMessage=$event">click with myClick</div>
<!-- #enddocregion my-click --> <!-- #enddocregion my-click -->
<!-- #enddocregion event-binding-3 --> <!-- #enddocregion event-binding-3 -->
{{clickity}} {{clickMessage}}
</div> </div>
@ -567,8 +567,8 @@ After setClasses(), the classes are "{{classDiv.className}}"
</hero-detail> </hero-detail>
<!-- #enddocregion io-2 --> <!-- #enddocregion io-2 -->
<div myClick2 (myClick)="clicked2=$event">myClick2</div> <div myClick2 (myClick)="clickMessage2=$event">myClick2</div>
{{clicked2}} {{clickMessage2}}
<!-- Pipes --> <!-- Pipes -->
<hr><h2>Pipes</h2> <hr><h2>Pipes</h2>

View File

@ -4,14 +4,17 @@ import {Directive, Output, ElementRef, EventEmitter} from 'angular2/core';
@Directive({selector:'[myClick]'}) @Directive({selector:'[myClick]'})
export class MyClickDirective { export class MyClickDirective {
// #docregion my-click-output-1 // #docregion my-click-output-1
@Output('myClick') clicks = new EventEmitter<string>(); @Output('myClick') clicks = new EventEmitter<string>(); // @Output(alias) propertyName = ...
// #enddocregion my-click-output-1 // #enddocregion my-click-output-1
constructor(el: ElementRef){ constructor(el: ElementRef){
el.nativeElement el.nativeElement
.addEventListener('click', (event:Event) => { .addEventListener('click', (event:Event) => {
this.clicks.emit('Click!'); this._toggle = !this._toggle;
this.clicks.emit(this._toggle ? 'Click!' : '');
}); });
} }
_toggle = false;
} }
// #docregion my-click-output-2 // #docregion my-click-output-2
@ -19,15 +22,18 @@ export class MyClickDirective {
// #enddocregion my-click-output-2 // #enddocregion my-click-output-2
selector:'[myClick2]', selector:'[myClick2]',
// #docregion my-click-output-2 // #docregion my-click-output-2
outputs:['clicks:myClick'] outputs:['clicks:myClick'] // propertyName:alias
}) })
// #enddocregion my-click-output-2 // #enddocregion my-click-output-2
export class MyClickDirective2 { export class MyClickDirective2 {
clicks = new EventEmitter<string>(); clicks = new EventEmitter<string>();
constructor(el: ElementRef){ constructor(el: ElementRef){
el.nativeElement el.nativeElement
.addEventListener('click', (event:Event) => { .addEventListener('click', (event:Event) => {
this.clicks.emit('Click!'); this._toggle = !this._toggle;
this.clicks.emit(this._toggle ? 'Click2!' : '');
}); });
} }
_toggle = false;
} }

View File

@ -101,7 +101,7 @@ include ../../../../_includes/_util-fns
We write template expressions in a language that looks like JavaScript. We write template expressions in a language that looks like JavaScript.
Many JavaScript expressions are legal template expressions but not all. Many JavaScript expressions are legal template expressions but not all.
JavaScript expressions that have or promote side-effects are prohibited including: JavaScript expressions that have or promote side-effects are prohibited including:
* assignment (`=`) * assignments (`=`, `+=`, `-=`)
* the `new` operator * the `new` operator
* chaining expressions with `;` or `,` * chaining expressions with `;` or `,`
* increment and decrement operators, `++` and `--`. * increment and decrement operators, `++` and `--`.
@ -191,11 +191,12 @@ include ../../../../_includes/_util-fns
:marked :marked
Angular template statements are also written in a language that looks like JavaScript. Angular template statements are also written in a language that looks like JavaScript.
The template statement parser is different than the template expression parser and The template statement parser is different than the template expression parser and
specifically supports both assignment (=) and chaining expressions with semicolons (;) and commas (,). specifically supports both basic assignment (=) and chaining expressions with semicolons (;) and commas (,).
However, certain JavaScript syntax is not allowed: However, certain JavaScript syntax is not allowed:
* the `new` operator * the `new` operator
* increment and decrement operators, `++` and `--` * increment and decrement operators, `++` and `--`
* operator assignment, e.g. `+=`, `-=`
* bit-wise operators, `|` and `&` * bit-wise operators, `|` and `&`
* the [template expression operators](#expression-operators) * the [template expression operators](#expression-operators)
@ -1172,28 +1173,30 @@ figure.image-display
This is frequently the case with [Attribute Directives](attribute-directives.html). This is frequently the case with [Attribute Directives](attribute-directives.html).
Directive consumers expect to bind to the name of the directive. Directive consumers expect to bind to the name of the directive.
For example, we expect to bind to the `myClick` event property of the `MyClickDirective`. 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`.
The directive name is often a poor choice for the the internal property name
because it rarely describes what the property does.
`myClick` is not a good name for a property that emits click events.
Fortunately, we can have a public name for the property that meets conventional expectations
and use a different name internally
by providing a public alias for the internal property name in the decorator like this:
+makeExample('template-syntax/ts/app/my-click.directive.ts', 'my-click-output-1')(format=".")
:marked
Now the directive name, `myClick`, is the public facing property name to which we can bind
+makeExample('template-syntax/ts/app/app.component.html', 'my-click')(format=".") +makeExample('template-syntax/ts/app/app.component.html', 'my-click')(format=".")
:marked :marked
while inside the directive, the property is known as `clicks`. However, the directive name is often a poor choice for the the name of a property within the directive class.
The directive name rarely describes what the property does.
The `myClick` directive name is not a good name for a property that emits click messages.
Fortunately, we can have a public name for the property that meets conventional expectations
while using a different name internally.
In the example immediately above, we are actually binding *through the* `myClick` *alias* to
the directive's own `clicks` property.
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=".")
:marked
With aliasing we please both the directive consumer and the directive author.
.l-sub-section .l-sub-section
:marked :marked
We can alias property names in the `inputs` and `outputs` arrays as well. We can also alias property names in the `inputs` and `outputs` arrays.
We write a colon-delimited string with We write a *colon-delimited* (:) string with
the internal property name on the left and the public name on the right: 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/my-click.directive.ts', 'my-click-output-2')(format=".")
<a id="expression-operators"></a> <a id="expression-operators"></a>