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 #7158

Closes #8264
This commit is contained in:
Tobias Bosch
2016-04-28 01:13:40 +00:00
parent ff2ae7a2e1
commit d2efac18ed
69 changed files with 651 additions and 414 deletions
@@ -14,7 +14,7 @@ Removes or recreates a portion of the DOM tree based on the showSection expressi
@cheatsheetItem
syntax:
`<li *ngFor="#item of list">`|`*ngFor`
`<li *ngFor="let item of list">`|`*ngFor`
description:
Turns the li element and its contents into a template, and uses that to instantiate a view for each item in list.
+1 -1
View File
@@ -433,7 +433,7 @@ Finally, we can move the `ngFor` keyword to the left hand side and prefix it wit
```
<ul>
<li *ngFor="var person of people; var i=index">{{i}}. {{person}}<li>
<li *ngFor="let person of people; var i=index">{{i}}. {{person}}<li>
</ul>
```
+1 -1
View File
@@ -94,7 +94,7 @@ Let's start with a View such as:
```
<ul>
<li template="ngFor: #person of people">{{person}}</li>
<li template="ngFor: let person of people">{{person}}</li>
</ul>
```
@@ -22,7 +22,7 @@ export class SlicePipeStringExample {
@Component({
selector: 'slice-list-example',
template: `<div>
<li *ngFor="var i of collection | slice:1:3">{{i}}</li>
<li *ngFor="let i of collection | slice:1:3">{{i}}</li>
</div>`
})
export class SlicePipeListExample {
@@ -36,7 +36,7 @@ class MyCmp implements OnDeactivate {
<router-outlet></router-outlet>
<div id="log">
<h2>Log:</h2>
<p *ngFor="#logItem of logService.logs">{{ logItem }}</p>
<p *ngFor="let logItem of logService.logs">{{ logItem }}</p>
</div>
`,
directives: [ROUTER_DIRECTIVES]
+2 -2
View File
@@ -56,7 +56,7 @@ export {URLSearchParams} from './src/http/url_search_params';
* <div>
* <h1>People</h1>
* <ul>
* <li *ngFor="#person of people">
* <li *ngFor="let person of people">
* {{person.name}}
* </li>
* </ul>
@@ -194,7 +194,7 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
* <div>
* <h1>People</h1>
* <ul>
* <li *ngFor="#person of people">
* <li *ngFor="let person of people">
* {{person.name}}
* </li>
* </ul>
@@ -58,7 +58,7 @@ import {BaseException} from "../../facade/exceptions";
*
* ### Syntax
*
* - `<li *ngFor="#item of items; #i = index">...</li>`
* - `<li *ngFor="let item of items; #i = index">...</li>`
* - `<li template="ngFor #item of items; #i = index">...</li>`
* - `<template ngFor #item [ngForOf]="items" #i="index"><li>...</li></template>`
*
@@ -96,7 +96,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
*
* ```
* <select ngControl="city">
* <option *ngFor="#c of cities" [value]="c"></option>
* <option *ngFor="let c of cities" [value]="c"></option>
* </select>
* ```
*/
@@ -46,7 +46,11 @@ export class Token {
isKeyword(): boolean { return (this.type == TokenType.Keyword); }
isKeywordVar(): boolean { return (this.type == TokenType.Keyword && this.strValue == "var"); }
isKeywordDeprecatedVar(): boolean {
return (this.type == TokenType.Keyword && this.strValue == "var");
}
isKeywordLet(): boolean { return (this.type == TokenType.Keyword && this.strValue == "let"); }
isKeywordNull(): boolean { return (this.type == TokenType.Keyword && this.strValue == "null"); }
@@ -464,4 +468,4 @@ var OPERATORS = SetWrapper.createFromList([
var KEYWORDS =
SetWrapper.createFromList(['var', 'null', 'undefined', 'true', 'false', 'if', 'else']);
SetWrapper.createFromList(['var', 'let', 'null', 'undefined', 'true', 'false', 'if', 'else']);
@@ -62,6 +62,10 @@ export class SplitInterpolation {
constructor(public strings: string[], public expressions: string[]) {}
}
export class TemplateBindingParseResult {
constructor(public templateBindings: TemplateBinding[], public warnings: string[]) {}
}
@Injectable()
export class Parser {
constructor(/** @internal */
@@ -112,7 +116,7 @@ export class Parser {
return new Quote(prefix, uninterpretedExpression, location);
}
parseTemplateBindings(input: string, location: any): TemplateBinding[] {
parseTemplateBindings(input: string, location: any): TemplateBindingParseResult {
var tokens = this._lexer.tokenize(input);
return new _ParseAST(input, location, tokens, false).parseTemplateBindings();
}
@@ -228,16 +232,11 @@ export class _ParseAST {
}
}
optionalKeywordVar(): boolean {
if (this.peekKeywordVar()) {
this.advance();
return true;
} else {
return false;
}
}
peekKeywordLet(): boolean { return this.next.isKeywordLet(); }
peekKeywordVar(): boolean { return this.next.isKeywordVar() || this.next.isOperator('#'); }
peekDeprecatedKeywordVar(): boolean { return this.next.isKeywordDeprecatedVar(); }
peekDeprecatedOperatorHash(): boolean { return this.next.isOperator('#'); }
expectCharacter(code: number) {
if (this.optionalCharacter(code)) return;
@@ -617,11 +616,23 @@ export class _ParseAST {
return result.toString();
}
parseTemplateBindings(): any[] {
var bindings = [];
parseTemplateBindings(): TemplateBindingParseResult {
var bindings: TemplateBinding[] = [];
var prefix = null;
var warnings: string[] = [];
while (this.index < this.tokens.length) {
var keyIsVar: boolean = this.optionalKeywordVar();
var keyIsVar: boolean = this.peekKeywordLet();
if (!keyIsVar && this.peekDeprecatedKeywordVar()) {
keyIsVar = true;
warnings.push(`"var" inside of expressions is deprecated. Use "let" instead!`);
}
if (!keyIsVar && this.peekDeprecatedOperatorHash()) {
keyIsVar = true;
warnings.push(`"#" inside of expressions is deprecated. Use "let" instead!`);
}
if (keyIsVar) {
this.advance();
}
var key = this.expectTemplateBindingKey();
if (!keyIsVar) {
if (prefix == null) {
@@ -639,7 +650,8 @@ export class _ParseAST {
} else {
name = '\$implicit';
}
} else if (this.next !== EOF && !this.peekKeywordVar()) {
} else if (this.next !== EOF && !this.peekKeywordLet() && !this.peekDeprecatedKeywordVar() &&
!this.peekDeprecatedOperatorHash()) {
var start = this.inputIndex;
var ast = this.parsePipe();
var source = this.input.substring(start, this.inputIndex);
@@ -650,7 +662,7 @@ export class _ParseAST {
this.optionalCharacter($COMMA);
}
}
return bindings;
return new TemplateBindingParseResult(bindings, warnings);
}
error(message: string, index: number = null) {
+7 -1
View File
@@ -17,8 +17,14 @@ export class ParseSourceSpan {
}
}
export enum ParseErrorLevel {
WARNING,
FATAL
}
export abstract class ParseError {
constructor(public span: ParseSourceSpan, public msg: string) {}
constructor(public span: ParseSourceSpan, public msg: string,
public level: ParseErrorLevel = ParseErrorLevel.FATAL) {}
toString(): string {
var source = this.span.start.file.content;
@@ -6,7 +6,7 @@ import {
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
VariableAst,
ReferenceAst,
BoundEventAst,
BoundElementPropertyAst,
AttrAst,
@@ -69,7 +69,7 @@ export class ProviderElementContext {
constructor(private _viewContext: ProviderViewContext, private _parent: ProviderElementContext,
private _isViewRoot: boolean, private _directiveAsts: DirectiveAst[],
attrs: AttrAst[], vars: VariableAst[], private _sourceSpan: ParseSourceSpan) {
attrs: AttrAst[], refs: ReferenceAst[], private _sourceSpan: ParseSourceSpan) {
this._attrs = {};
attrs.forEach((attrAst) => this._attrs[attrAst.name] = attrAst.value);
var directivesMeta = _directiveAsts.map(directiveAst => directiveAst.directive);
@@ -79,9 +79,8 @@ export class ProviderElementContext {
var queriedTokens = new CompileTokenMap<boolean>();
this._allProviders.values().forEach(
(provider) => { this._addQueryReadsTo(provider.token, queriedTokens); });
vars.forEach((varAst) => {
var varToken = new CompileTokenMetadata({value: varAst.name});
this._addQueryReadsTo(varToken, queriedTokens);
refs.forEach((refAst) => {
this._addQueryReadsTo(new CompileTokenMetadata({value: refAst.name}), queriedTokens);
});
if (isPresent(queriedTokens.get(identifierToken(Identifiers.ViewContainerRef)))) {
this._hasViewContainer = true;
@@ -30,7 +30,6 @@ import {
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
AttrAst,
+17 -12
View File
@@ -82,7 +82,18 @@ export class BoundEventAst implements TemplateAst {
}
/**
* A variable declaration on an element (e.g. `#var="expression"`).
* A reference declaration on an element (e.g. `let someName="expression"`).
*/
export class ReferenceAst implements TemplateAst {
constructor(public name: string, public value: CompileTokenMetadata,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitReference(this, context);
}
}
/**
* A variable declaration on a <template> (e.g. `var-someName="someLocalName"`).
*/
export class VariableAst implements TemplateAst {
constructor(public name: string, public value: string, public sourceSpan: ParseSourceSpan) {}
@@ -97,7 +108,7 @@ export class VariableAst implements TemplateAst {
export class ElementAst implements TemplateAst {
constructor(public name: string, public attrs: AttrAst[],
public inputs: BoundElementPropertyAst[], public outputs: BoundEventAst[],
public exportAsVars: VariableAst[], public directives: DirectiveAst[],
public references: ReferenceAst[], public directives: DirectiveAst[],
public providers: ProviderAst[], public hasViewContainer: boolean,
public children: TemplateAst[], public ngContentIndex: number,
public sourceSpan: ParseSourceSpan) {}
@@ -106,14 +117,6 @@ export class ElementAst implements TemplateAst {
return visitor.visitElement(this, context);
}
/**
* Whether the element has any active bindings (inputs, outputs, vars, or directives).
*/
isBound(): boolean {
return (this.inputs.length > 0 || this.outputs.length > 0 || this.exportAsVars.length > 0 ||
this.directives.length > 0);
}
/**
* Get the component associated with this element, if any.
*/
@@ -132,7 +135,8 @@ export class ElementAst implements TemplateAst {
* A `<template>` element included in an Angular template.
*/
export class EmbeddedTemplateAst implements TemplateAst {
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[],
public references: ReferenceAst[], public variables: VariableAst[],
public directives: DirectiveAst[], public providers: ProviderAst[],
public hasViewContainer: boolean, public children: TemplateAst[],
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
@@ -160,7 +164,7 @@ export class DirectiveAst implements TemplateAst {
constructor(public directive: CompileDirectiveMetadata,
public inputs: BoundDirectivePropertyAst[],
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
public exportAsVars: VariableAst[], public sourceSpan: ParseSourceSpan) {}
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitDirective(this, context);
}
@@ -232,6 +236,7 @@ export interface TemplateAstVisitor {
visitNgContent(ast: NgContentAst, context: any): any;
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any;
visitElement(ast: ElementAst, context: any): any;
visitReference(ast: ReferenceAst, context: any): any;
visitVariable(ast: VariableAst, context: any): any;
visitEvent(ast: BoundEventAst, context: any): any;
visitElementProperty(ast: BoundElementPropertyAst, context: any): any;
File diff suppressed because it is too large Load Diff
@@ -4,7 +4,7 @@ import {InjectMethodVars} from './constants';
import {CompileView} from './compile_view';
import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {TemplateAst, ProviderAst, ProviderAstType} from '../template_ast';
import {TemplateAst, ProviderAst, ProviderAstType, ReferenceAst} from '../template_ast';
import {
CompileTokenMap,
CompileDirectiveMetadata,
@@ -13,7 +13,7 @@ import {
CompileProviderMetadata,
CompileDiDependencyMetadata,
CompileIdentifierMetadata,
CompileTypeMetadata
CompileTypeMetadata,
} from '../compile_metadata';
import {getPropertyInView, createDiTokenExpression, injectFromViewParentInjector} from './util';
import {CompileQuery, createQueryList, addQueryToTokenMap} from './compile_query';
@@ -30,7 +30,7 @@ export class CompileNode {
export class CompileElement extends CompileNode {
static createNull(): CompileElement {
return new CompileElement(null, null, null, null, null, null, [], [], false, false, {});
return new CompileElement(null, null, null, null, null, null, [], [], false, false, []);
}
private _compViewExpr: o.Expression = null;
@@ -47,15 +47,18 @@ export class CompileElement extends CompileNode {
public contentNodesByNgContentIndex: Array<o.Expression>[] = null;
public embeddedView: CompileView;
public directiveInstances: o.Expression[];
public referenceTokens: {[key: string]: CompileTokenMetadata};
constructor(parent: CompileElement, view: CompileView, nodeIndex: number,
renderNode: o.Expression, sourceAst: TemplateAst,
public component: CompileDirectiveMetadata,
private _directives: CompileDirectiveMetadata[],
private _resolvedProvidersArray: ProviderAst[], public hasViewContainer: boolean,
public hasEmbeddedView: boolean,
public variableTokens: {[key: string]: CompileTokenMetadata}) {
public hasEmbeddedView: boolean, references: ReferenceAst[]) {
super(parent, view, nodeIndex, renderNode, sourceAst);
this.referenceTokens = {};
references.forEach(ref => this.referenceTokens[ref.name] = ref.value);
this.elementRef = o.importExpr(Identifiers.ElementRef).instantiate([this.renderNode]);
this._instances.add(identifierToken(Identifiers.ElementRef), this.elementRef);
this.injector = o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]);
@@ -167,15 +170,15 @@ export class CompileElement extends CompileNode {
queriesWithReads,
queriesForProvider.map(query => new _QueryWithRead(query, resolvedProvider.token)));
});
StringMapWrapper.forEach(this.variableTokens, (_, varName) => {
var token = this.variableTokens[varName];
StringMapWrapper.forEach(this.referenceTokens, (_, varName) => {
var token = this.referenceTokens[varName];
var varValue;
if (isPresent(token)) {
varValue = this._instances.get(token);
} else {
varValue = this.renderNode;
}
this.view.variables.set(varName, varValue);
this.view.locals.set(varName, varValue);
var varToken = new CompileTokenMetadata({value: varName});
ListWrapper.addAll(queriesWithReads, this._getQueriesFor(varToken)
.map(query => new _QueryWithRead(query, varToken)));
@@ -186,8 +189,8 @@ export class CompileElement extends CompileNode {
// query for an identifier
value = this._instances.get(queryWithRead.read);
} else {
// query for a variable
var token = this.variableTokens[queryWithRead.read.value];
// query for a reference
var token = this.referenceTokens[queryWithRead.read.value];
if (isPresent(token)) {
value = this._instances.get(token);
} else {
@@ -247,12 +250,6 @@ export class CompileElement extends CompileNode {
(resolvedProvider) => createDiTokenExpression(resolvedProvider.token));
}
getDeclaredVariablesNames(): string[] {
var res = [];
StringMapWrapper.forEach(this.variableTokens, (_, key) => { res.push(key); });
return res;
}
private _getQueriesFor(token: CompileTokenMetadata): CompileQuery[] {
var result: CompileQuery[] = [];
var currentEl: CompileElement = this;
@@ -56,7 +56,7 @@ export class CompileView implements NameResolver {
public componentView: CompileView;
public purePipes = new Map<string, CompilePipe>();
public pipes: CompilePipe[] = [];
public variables = new Map<string, o.Expression>();
public locals = new Map<string, o.Expression>();
public className: string;
public classType: o.Type;
public viewFactory: o.ReadVarExpr;
@@ -112,7 +112,7 @@ export class CompileView implements NameResolver {
}
this.viewQueries = viewQueries;
templateVariableBindings.forEach((entry) => {
this.variables.set(entry[1], o.THIS_EXPR.prop('locals').key(o.literal(entry[0])));
this.locals.set(entry[1], o.THIS_EXPR.prop('locals').key(o.literal(entry[0])));
});
if (!this.declarationElement.isNull()) {
@@ -133,15 +133,15 @@ export class CompileView implements NameResolver {
return pipe.call(this, [input].concat(args));
}
getVariable(name: string): o.Expression {
getLocal(name: string): o.Expression {
if (name == EventHandlerVars.event.name) {
return EventHandlerVars.event;
}
var currView: CompileView = this;
var result = currView.variables.get(name);
var result = currView.locals.get(name);
while (isBlank(result) && isPresent(currView.declarationElement.view)) {
currView = currView.declarationElement.view;
result = currView.variables.get(name);
result = currView.locals.get(name);
}
if (isPresent(result)) {
return getPropertyInView(result, this, currView);
@@ -9,7 +9,7 @@ var IMPLICIT_RECEIVER = o.variable('#implicit');
export interface NameResolver {
callPipe(name: string, input: o.Expression, args: o.Expression[]): o.Expression;
getVariable(name: string): o.Expression;
getLocal(name: string): o.Expression;
createLiteralArray(values: o.Expression[]): o.Expression;
createLiteralMap(values: Array<Array<string | o.Expression>>): o.Expression;
}
@@ -185,7 +185,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
var result = null;
var receiver = ast.receiver.visit(this, _Mode.Expression);
if (receiver === IMPLICIT_RECEIVER) {
var varExpr = this._nameResolver.getVariable(ast.name);
var varExpr = this._nameResolver.getLocal(ast.name);
if (isPresent(varExpr)) {
result = varExpr.callFn(args);
} else {
@@ -204,7 +204,7 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
var result = null;
var receiver = ast.receiver.visit(this, _Mode.Expression);
if (receiver === IMPLICIT_RECEIVER) {
result = this._nameResolver.getVariable(ast.name);
result = this._nameResolver.getLocal(ast.name);
if (isBlank(result)) {
receiver = this._implicitReceiver;
}
@@ -217,9 +217,9 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
visitPropertyWrite(ast: cdAst.PropertyWrite, mode: _Mode): any {
var receiver: o.Expression = ast.receiver.visit(this, _Mode.Expression);
if (receiver === IMPLICIT_RECEIVER) {
var varExpr = this._nameResolver.getVariable(ast.name);
var varExpr = this._nameResolver.getLocal(ast.name);
if (isPresent(varExpr)) {
throw new BaseException('Cannot reassign a variable binding');
throw new BaseException('Cannot assign to a reference or variable!');
}
receiver = this._implicitReceiver;
}
@@ -7,6 +7,7 @@ import {
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
ReferenceAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
@@ -113,6 +114,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
return null;
}
visitReference(ast: ReferenceAst, ctx: any): any { return null; }
visitVariable(ast: VariableAst, ctx: any): any { return null; }
visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { return null; }
visitElementProperty(ast: BoundElementPropertyAst, context: any): any { return null; }
@@ -26,6 +26,7 @@ import {
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
ReferenceAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
@@ -201,8 +202,6 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
var component = ast.getComponent();
var directives = ast.directives.map(directiveAst => directiveAst.directive);
var variables =
_readHtmlAndDirectiveVariables(ast.exportAsVars, ast.directives, this.view.viewType);
var htmlAttrs = _readHtmlAttrs(ast.attrs);
var attrNameAndValues = _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives);
for (var i = 0; i < attrNameAndValues.length; i++) {
@@ -216,7 +215,7 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
}
var compileElement =
new CompileElement(parent, this.view, nodeIndex, renderNode, ast, component, directives,
ast.providers, ast.hasViewContainer, false, variables);
ast.providers, ast.hasViewContainer, false, ast.references);
this.view.nodes.push(compileElement);
var compViewExpr: o.ReadVarExpr = null;
if (isPresent(component)) {
@@ -269,13 +268,13 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
.toStmt());
var renderNode = o.THIS_EXPR.prop(fieldName);
var templateVariableBindings = ast.vars.map(
var templateVariableBindings = ast.variables.map(
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
var directives = ast.directives.map(directiveAst => directiveAst.directive);
var compileElement =
new CompileElement(parent, this.view, nodeIndex, renderNode, ast, null, directives,
ast.providers, ast.hasViewContainer, true, {});
ast.providers, ast.hasViewContainer, true, ast.references);
this.view.nodes.push(compileElement);
this.nestedViewCount++;
@@ -297,6 +296,7 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
return null;
}
visitReference(ast: ReferenceAst, ctx: any): any { return null; }
visitVariable(ast: VariableAst, ctx: any): any { return null; }
visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { return null; }
visitElementProperty(ast: BoundElementPropertyAst, context: any): any { return null; }
@@ -321,24 +321,6 @@ function _readHtmlAttrs(attrs: AttrAst[]): {[key: string]: string} {
return htmlAttrs;
}
function _readHtmlAndDirectiveVariables(elementExportAsVars: VariableAst[],
directives: DirectiveAst[],
viewType: ViewType): {[key: string]: CompileTokenMetadata} {
var variables: {[key: string]: CompileTokenMetadata} = {};
var component: CompileDirectiveMetadata = null;
directives.forEach((directive) => {
if (directive.directive.isComponent) {
component = directive.directive;
}
directive.exportAsVars.forEach(
varAst => { variables[varAst.name] = identifierToken(directive.directive.type); });
});
elementExportAsVars.forEach((varAst) => {
variables[varAst.name] = isPresent(component) ? identifierToken(component.type) : null;
});
return variables;
}
function mergeAttributeValue(attrName: string, attrValue1: string, attrValue2: string): string {
if (attrName == CLASS_ATTR || attrName == STYLE_ATTR) {
return `${attrValue1} ${attrValue2}`;
@@ -392,7 +374,7 @@ function createStaticNodeDebugInfo(node: CompileNode): o.Expression {
if (isPresent(compileElement.component)) {
componentToken = createDiTokenExpression(identifierToken(compileElement.component.type));
}
StringMapWrapper.forEach(compileElement.variableTokens, (token, varName) => {
StringMapWrapper.forEach(compileElement.referenceTokens, (token, varName) => {
varTokenEntries.push(
[varName, isPresent(token) ? createDiTokenExpression(token) : o.NULL_EXPR]);
});
@@ -70,7 +70,7 @@ export abstract class ChangeDetectorRef {
* @Component({
* selector: 'giant-list',
* template: `
* <li *ngFor="#d of dataProvider.data">Data {{d}}</lig>
* <li *ngFor="let d of dataProvider.data">Data {{d}}</lig>
* `,
* directives: [NgFor]
* })
+8 -2
View File
@@ -1,7 +1,13 @@
import {Injectable} from 'angular2/src/core/di';
import {print} from 'angular2/src/facade/lang';
import {print, warn} from 'angular2/src/facade/lang';
// Note: Need to rename warn as in Dart
// class members and imports can't use the same name.
let _warnImpl = warn;
@Injectable()
export class Console {
log(message: string): void { print(message); }
}
// Note: for reporting errors use `DOM.logError()` as it is platform specific
warn(message: string): void { _warnImpl(message); }
}
@@ -8,7 +8,7 @@ import {ViewType} from './view_type';
@CONST()
export class StaticNodeDebugInfo {
constructor(public providerTokens: any[], public componentToken: any,
public varTokens: {[key: string]: any}) {}
public refTokens: {[key: string]: any}) {}
}
export class DebugContext implements RenderDebugInfo {
@@ -61,15 +61,15 @@ export class DebugContext implements RenderDebugInfo {
ListWrapper.forEachWithIndex(
this._view.staticNodeDebugInfos,
(staticNodeInfo: StaticNodeDebugInfo, nodeIndex: number) => {
var vars = staticNodeInfo.varTokens;
StringMapWrapper.forEach(vars, (varToken, varName) => {
var refs = staticNodeInfo.refTokens;
StringMapWrapper.forEach(refs, (refToken, refName) => {
var varValue;
if (isBlank(varToken)) {
if (isBlank(refToken)) {
varValue = isPresent(this._view.allNodes) ? this._view.allNodes[nodeIndex] : null;
} else {
varValue = this._view.injectorGet(varToken, nodeIndex, null);
varValue = this._view.injectorGet(refToken, nodeIndex, null);
}
varValues[varName] = varValue;
varValues[refName] = varValue;
});
});
StringMapWrapper.forEach(this._view.locals,
@@ -11,7 +11,7 @@ import {Observable, EventEmitter} from 'angular2/src/facade/async';
*
* Implements an iterable interface, therefore it can be used in both ES6
* javascript `for (var i of items)` loops as well as in Angular templates with
* `*ngFor="#i of myList"`.
* `*ngFor="let i of myList"`.
*
* Changes can be observed by subscribing to the changes `Observable`.
*
+2 -2
View File
@@ -34,7 +34,7 @@ export abstract class ViewRef extends ChangeDetectorRef {
* ```
* Count: {{items.length}}
* <ul>
* <li *ngFor="var item of items">{{item}}</li>
* <li *ngFor="let item of items">{{item}}</li>
* </ul>
* ```
*
@@ -44,7 +44,7 @@ export abstract class ViewRef extends ChangeDetectorRef {
* ```
* Count: {{items.length}}
* <ul>
* <template ngFor var-item [ngForOf]="items"></template>
* <template ngFor let-item [ngForOf]="items"></template>
* </ul>
* ```
*
+2 -2
View File
@@ -964,7 +964,7 @@ export var Attribute: AttributeMetadataFactory = makeParamDecorator(AttributeMet
* ```html
* <tabs>
* <pane title="Overview">...</pane>
* <pane *ngFor="#o of objects" [title]="o.title">{{o.text}}</pane>
* <pane *ngFor="let o of objects" [title]="o.title">{{o.text}}</pane>
* </tabs>
* ```
*
@@ -983,7 +983,7 @@ export var Attribute: AttributeMetadataFactory = makeParamDecorator(AttributeMet
* selector: 'tabs',
* template: `
* <ul>
* <li *ngFor="#pane of panes">{{pane.title}}</li>
* <li *ngFor="let pane of panes">{{pane.title}}</li>
* </ul>
* <ng-content></ng-content>
* `
+2 -2
View File
@@ -46,7 +46,7 @@ export class AttributeMetadata extends DependencyMetadata {
* ```html
* <tabs>
* <pane title="Overview">...</pane>
* <pane *ngFor="#o of objects" [title]="o.title">{{o.text}}</pane>
* <pane *ngFor="let o of objects" [title]="o.title">{{o.text}}</pane>
* </tabs>
* ```
*
@@ -65,7 +65,7 @@ export class AttributeMetadata extends DependencyMetadata {
* selector: 'tabs',
* template: `
* <ul>
* <li *ngFor="#pane of panes">{{pane.title}}</li>
* <li *ngFor="let pane of panes">{{pane.title}}</li>
* </ul>
* <ng-content></ng-content>
* `
@@ -149,7 +149,7 @@ export interface OnInit { ngOnInit(); }
* template: `
* <p>Changes:</p>
* <ul>
* <li *ngFor="#line of logs">{{line}}</li>
* <li *ngFor="let line of logs">{{line}}</li>
* </ul>`,
* directives: [NgFor]
* })
+1 -1
View File
@@ -104,7 +104,7 @@ export class ViewMetadata {
* directives: [NgFor]
* template: '
* <ul>
* <li *ngFor="#item of items">{{item}}</li>
* <li *ngFor="let item of items">{{item}}</li>
* </ul>'
* })
* class MyComponent {
+4
View File
@@ -298,6 +298,10 @@ bool isJsObject(o) {
return false;
}
warn(o) {
print(o);
}
// Functions below are noop in Dart. Imperatively controlling dev mode kills
// tree shaking. We should only rely on `assertionsEnabled`.
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')

Some files were not shown because too many files have changed in this diff Show More