Skip to content

Commit d2efac1

Browse files
committed
feat(core): separate refs from vars.
Introduces `ref-` to give a name to an element or a directive (also works for `<template>` elements), and `let-` to introduce an input variable for a `<template>` element. BREAKING CHANGE: - `#...` now always means `ref-`. - `<template #abc>` now defines a reference to the TemplateRef, instead of an input variable used inside of the template. - `#...` inside of a *ngIf, … directives is deprecated. Use `let …` instead. - `var-...` is deprecated. Replace with `let-...` for `<template>` elements and `ref-` for non `<template>` elements. Closes angular#7158 Closes angular#8264
1 parent ff2ae7a commit d2efac1

69 files changed

Lines changed: 643 additions & 406 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

modules/angular2/docs/cheatsheet/built-in-directives.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Removes or recreates a portion of the DOM tree based on the showSection expressi
1414

1515
@cheatsheetItem
1616
syntax:
17-
`<li *ngFor="#item of list">`|`*ngFor`
17+
`<li *ngFor="let item of list">`|`*ngFor`
1818
description:
1919
Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.
2020

modules/angular2/docs/core/01_templates.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ Finally, we can move the `ngFor` keyword to the left hand side and prefix it wit
433433

434434
```
435435
<ul>
436-
<li *ngFor="var person of people; var i=index">{{i}}. {{person}}<li>
436+
<li *ngFor="let person of people; var i=index">{{i}}. {{person}}<li>
437437
</ul>
438438
```
439439

modules/angular2/docs/core/10_view.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ Let's start with a View such as:
9494

9595
```
9696
<ul>
97-
<li template="ngFor: #person of people">{{person}}</li>
97+
<li template="ngFor: let person of people">{{person}}</li>
9898
</ul>
9999
```
100100

modules/angular2/examples/core/pipes/ts/slice_pipe/slice_pipe_example.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export class SlicePipeStringExample {
2222
@Component({
2323
selector: 'slice-list-example',
2424
template: `<div>
25-
<li *ngFor="var i of collection | slice:1:3">{{i}}</li>
25+
<li *ngFor="let i of collection | slice:1:3">{{i}}</li>
2626
</div>`
2727
})
2828
export class SlicePipeListExample {

modules/angular2/examples/router/ts/on_deactivate/on_deactivate_example.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class MyCmp implements OnDeactivate {
3636
<router-outlet></router-outlet>
3737
<div id="log">
3838
<h2>Log:</h2>
39-
<p *ngFor="#logItem of logService.logs">{{ logItem }}</p>
39+
<p *ngFor="let logItem of logService.logs">{{ logItem }}</p>
4040
</div>
4141
`,
4242
directives: [ROUTER_DIRECTIVES]

modules/angular2/http.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export {URLSearchParams} from './src/http/url_search_params';
5656
* <div>
5757
* <h1>People</h1>
5858
* <ul>
59-
* <li *ngFor="#person of people">
59+
* <li *ngFor="let person of people">
6060
* {{person.name}}
6161
* </li>
6262
* </ul>
@@ -194,7 +194,7 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
194194
* <div>
195195
* <h1>People</h1>
196196
* <ul>
197-
* <li *ngFor="#person of people">
197+
* <li *ngFor="let person of people">
198198
* {{person.name}}
199199
* </li>
200200
* </ul>

modules/angular2/src/common/directives/ng_for.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import {BaseException} from "../../facade/exceptions";
5858
*
5959
* ### Syntax
6060
*
61-
* - `<li *ngFor="#item of items; #i = index">...</li>`
61+
* - `<li *ngFor="let item of items; #i = index">...</li>`
6262
* - `<li template="ngFor #item of items; #i = index">...</li>`
6363
* - `<template ngFor #item [ngForOf]="items" #i="index"><li>...</li></template>`
6464
*

modules/angular2/src/common/forms/directives/select_control_value_accessor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
9696
*
9797
* ```
9898
* <select ngControl="city">
99-
* <option *ngFor="#c of cities" [value]="c"></option>
99+
* <option *ngFor="let c of cities" [value]="c"></option>
100100
* </select>
101101
* ```
102102
*/

modules/angular2/src/compiler/expression_parser/lexer.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ export class Token {
4646

4747
isKeyword(): boolean { return (this.type == TokenType.Keyword); }
4848

49-
isKeywordVar(): boolean { return (this.type == TokenType.Keyword && this.strValue == "var"); }
49+
isKeywordDeprecatedVar(): boolean {
50+
return (this.type == TokenType.Keyword && this.strValue == "var");
51+
}
52+
53+
isKeywordLet(): boolean { return (this.type == TokenType.Keyword && this.strValue == "let"); }
5054

5155
isKeywordNull(): boolean { return (this.type == TokenType.Keyword && this.strValue == "null"); }
5256

@@ -464,4 +468,4 @@ var OPERATORS = SetWrapper.createFromList([
464468

465469

466470
var KEYWORDS =
467-
SetWrapper.createFromList(['var', 'null', 'undefined', 'true', 'false', 'if', 'else']);
471+
SetWrapper.createFromList(['var', 'let', 'null', 'undefined', 'true', 'false', 'if', 'else']);

modules/angular2/src/compiler/expression_parser/parser.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export class SplitInterpolation {
6262
constructor(public strings: string[], public expressions: string[]) {}
6363
}
6464

65+
export class TemplateBindingParseResult {
66+
constructor(public templateBindings: TemplateBinding[], public warnings: string[]) {}
67+
}
68+
6569
@Injectable()
6670
export class Parser {
6771
constructor(/** @internal */
@@ -112,7 +116,7 @@ export class Parser {
112116
return new Quote(prefix, uninterpretedExpression, location);
113117
}
114118

115-
parseTemplateBindings(input: string, location: any): TemplateBinding[] {
119+
parseTemplateBindings(input: string, location: any): TemplateBindingParseResult {
116120
var tokens = this._lexer.tokenize(input);
117121
return new _ParseAST(input, location, tokens, false).parseTemplateBindings();
118122
}
@@ -228,16 +232,11 @@ export class _ParseAST {
228232
}
229233
}
230234

231-
optionalKeywordVar(): boolean {
232-
if (this.peekKeywordVar()) {
233-
this.advance();
234-
return true;
235-
} else {
236-
return false;
237-
}
238-
}
235+
peekKeywordLet(): boolean { return this.next.isKeywordLet(); }
236+
237+
peekDeprecatedKeywordVar(): boolean { return this.next.isKeywordDeprecatedVar(); }
239238

240-
peekKeywordVar(): boolean { return this.next.isKeywordVar() || this.next.isOperator('#'); }
239+
peekDeprecatedOperatorHash(): boolean { return this.next.isOperator('#'); }
241240

242241
expectCharacter(code: number) {
243242
if (this.optionalCharacter(code)) return;
@@ -617,11 +616,23 @@ export class _ParseAST {
617616
return result.toString();
618617
}
619618

620-
parseTemplateBindings(): any[] {
621-
var bindings = [];
619+
parseTemplateBindings(): TemplateBindingParseResult {
620+
var bindings: TemplateBinding[] = [];
622621
var prefix = null;
622+
var warnings: string[] = [];
623623
while (this.index < this.tokens.length) {
624-
var keyIsVar: boolean = this.optionalKeywordVar();
624+
var keyIsVar: boolean = this.peekKeywordLet();
625+
if (!keyIsVar && this.peekDeprecatedKeywordVar()) {
626+
keyIsVar = true;
627+
warnings.push(`"var" inside of expressions is deprecated. Use "let" instead!`);
628+
}
629+
if (!keyIsVar && this.peekDeprecatedOperatorHash()) {
630+
keyIsVar = true;
631+
warnings.push(`"#" inside of expressions is deprecated. Use "let" instead!`);
632+
}
633+
if (keyIsVar) {
634+
this.advance();
635+
}
625636
var key = this.expectTemplateBindingKey();
626637
if (!keyIsVar) {
627638
if (prefix == null) {
@@ -639,7 +650,8 @@ export class _ParseAST {
639650
} else {
640651
name = '\$implicit';
641652
}
642-
} else if (this.next !== EOF && !this.peekKeywordVar()) {
653+
} else if (this.next !== EOF && !this.peekKeywordLet() && !this.peekDeprecatedKeywordVar() &&
654+
!this.peekDeprecatedOperatorHash()) {
643655
var start = this.inputIndex;
644656
var ast = this.parsePipe();
645657
var source = this.input.substring(start, this.inputIndex);
@@ -650,7 +662,7 @@ export class _ParseAST {
650662
this.optionalCharacter($COMMA);
651663
}
652664
}
653-
return bindings;
665+
return new TemplateBindingParseResult(bindings, warnings);
654666
}
655667

656668
error(message: string, index: number = null) {

0 commit comments

Comments
 (0)