diff --git a/aio/content/cheatsheet/built-in-directives.md b/aio/content/cheatsheet/built-in-directives.md
index beedbd665d..d82be6a129 100644
--- a/aio/content/cheatsheet/built-in-directives.md
+++ b/aio/content/cheatsheet/built-in-directives.md
@@ -20,9 +20,9 @@ Turns the li element and its contents into a template, and uses that to instanti
@cheatsheetItem
syntax:
`
- ...
- ...
- ...
+ ...
+ ...
+ ...
`|`[ngSwitch]`|`[ngSwitchCase]`|`ngSwitchCase`|`ngSwitchDefault`
description:
Conditionally swaps the contents of the div by selecting one of the embedded templates based on the current value of `conditionExpression`.
diff --git a/aio/content/cheatsheet/template-syntax.md b/aio/content/cheatsheet/template-syntax.md
index f2d1fa7953..1984273b4b 100644
--- a/aio/content/cheatsheet/template-syntax.md
+++ b/aio/content/cheatsheet/template-syntax.md
@@ -65,7 +65,7 @@ syntax:
`
...
`|`*myUnless`
description:
The `*` symbol turns the current element into an embedded template. Equivalent to:
-`
`
*
- * With `` element:
+ * With `` element:
*
* ```
- *
+ *
*
...
- *
+ *
* ```
*
* ### Example
diff --git a/modules/@angular/common/src/directives/ng_if.ts b/modules/@angular/common/src/directives/ng_if.ts
index fc6f42a7ef..ccb28a47f0 100644
--- a/modules/@angular/common/src/directives/ng_if.ts
+++ b/modules/@angular/common/src/directives/ng_if.ts
@@ -26,7 +26,7 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '
* # Showing an alternative template using `else`
*
* If it is necessary to display a template when the `expression` is falsy use the `else` template
- * binding as shown. Note that the `else` binding points to a `` labeled `#elseBlock`.
+ * binding as shown. Note that the `else` binding points to a `` labeled `#elseBlock`.
* The template can be defined anywhere in the component view but is typically placed right after
* `ngIf` for readability.
*
@@ -76,25 +76,25 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '
* Simple form:
* - `
...
`
* - `
...
`
- * - `
...
`
+ * - `
...
`
*
* Form with an else block:
* ```
*
...
- * ...
+ * ...
* ```
*
* Form with a `then` and `else` block:
* ```
*
- * ...
- * ...
+ * ...
+ * ...
* ```
*
* Form with storing the value locally:
* ```
*
';
fixture = createTestComponent(template);
getComponent().items = ['a', 'b', 'c'];
fixture.detectChanges();
@@ -262,7 +262,7 @@ export function main() {
it('should use a custom template when both default and a custom one are present', async(() => {
const template =
'{{i}};' +
- '{{i}}: {{item}};';
+ '{{i}}: {{item}};';
fixture = createTestComponent(template);
getComponent().items = ['a', 'b', 'c'];
fixture.detectChanges();
diff --git a/modules/@angular/common/test/directives/ng_if_spec.ts b/modules/@angular/common/test/directives/ng_if_spec.ts
index efc875e975..44b7280365 100644
--- a/modules/@angular/common/test/directives/ng_if_spec.ts
+++ b/modules/@angular/common/test/directives/ng_if_spec.ts
@@ -37,7 +37,7 @@ export function main() {
}));
it('should work on a template element', async(() => {
- const template = 'hello2';
+ const template = 'hello2';
fixture = createTestComponent(template);
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText('hello2');
@@ -141,7 +141,7 @@ export function main() {
describe('else', () => {
it('should support else', async(() => {
const template = 'TRUE' +
- 'FALSE';
+ 'FALSE';
fixture = createTestComponent(template);
@@ -156,8 +156,8 @@ export function main() {
it('should support then and else', async(() => {
const template =
'IGNORE' +
- 'THEN' +
- 'ELSE';
+ 'THEN' +
+ 'ELSE';
fixture = createTestComponent(template);
@@ -172,8 +172,8 @@ export function main() {
it('should support dynamic else', async(() => {
const template =
'TRUE' +
- 'FALSE1' +
- 'FALSE2';
+ 'FALSE1' +
+ 'FALSE2';
fixture = createTestComponent(template);
@@ -191,7 +191,7 @@ export function main() {
it('should support binding to variable', async(() => {
const template = '{{v}}' +
- '{{v}}';
+ '{{v}}';
fixture = createTestComponent(template);
diff --git a/modules/@angular/common/test/directives/ng_plural_spec.ts b/modules/@angular/common/test/directives/ng_plural_spec.ts
index bd78843a07..3a19cfad4d 100644
--- a/modules/@angular/common/test/directives/ng_plural_spec.ts
+++ b/modules/@angular/common/test/directives/ng_plural_spec.ts
@@ -34,8 +34,8 @@ export function main() {
it('should display the template according to the exact value', async(() => {
const template = '
' +
- '
you have no messages.
' +
- '
you have one message.
' +
+ '
you have no messages.
' +
+ '
you have one message.
' +
'
';
fixture = createTestComponent(template);
@@ -67,7 +67,7 @@ export function main() {
// https://github.com/angular/angular/issues/9882
it('should not throw when ngPluralCase contains expressions', async(() => {
const template = '
' +
- '
{{ switchValue }}
' +
+ '
{{ switchValue }}
' +
'
';
fixture = createTestComponent(template);
@@ -79,8 +79,8 @@ export function main() {
it('should be applicable to elements', async(() => {
const template = '' +
- 'you have no messages.' +
- 'you have one message.' +
+ 'you have no messages.' +
+ 'you have one message.' +
'';
fixture = createTestComponent(template);
@@ -94,8 +94,8 @@ export function main() {
it('should display the template according to the category', async(() => {
const template = '
' +
- '
you have a few messages.
' +
- '
you have many messages.
' +
+ '
you have a few messages.
' +
+ '
you have many messages.
' +
'
';
fixture = createTestComponent(template);
@@ -109,8 +109,8 @@ export function main() {
it('should default to other when no matches are found', async(() => {
const template = '
' +
- '
you have a few messages.
' +
- '
default message.
' +
+ '
you have a few messages.
' +
+ '
default message.
' +
'
';
fixture = createTestComponent(template);
@@ -121,8 +121,8 @@ export function main() {
it('should prioritize value matches over category matches', async(() => {
const template = '
' +
- '
you have a few messages.
' +
- 'you have two messages.' +
+ '
you have a few messages.
' +
+ 'you have two messages.' +
'
';
fixture = createTestComponent(template);
diff --git a/modules/@angular/common/test/directives/ng_template_outlet_spec.ts b/modules/@angular/common/test/directives/ng_template_outlet_spec.ts
index df0b31189a..fb3cffd141 100644
--- a/modules/@angular/common/test/directives/ng_template_outlet_spec.ts
+++ b/modules/@angular/common/test/directives/ng_template_outlet_spec.ts
@@ -41,14 +41,14 @@ export function main() {
}));
it('should insert content specified by TemplateRef', async(() => {
- const template = `foo` +
+ const template = `foo` +
``;
fixture = createTestComponent(template);
detectChangesAndExpectText('foo');
}));
it('should clear content if TemplateRef becomes `null`', async(() => {
- const template = `foo` +
+ const template = `foo` +
``;
fixture = createTestComponent(template);
fixture.detectChanges();
@@ -63,7 +63,7 @@ export function main() {
it('should swap content if TemplateRef changes', async(() => {
const template =
- `foobar` +
+ `foobar` +
``;
fixture = createTestComponent(template);
@@ -78,14 +78,14 @@ export function main() {
}));
it('should display template if context is `null`', async(() => {
- const template = `foo` +
+ const template = `foo` +
``;
fixture = createTestComponent(template);
detectChangesAndExpectText('foo');
}));
it('should reflect initial context and changes', async(() => {
- const template = `{{foo}}` +
+ const template = `{{foo}}` +
``;
fixture = createTestComponent(template);
@@ -97,7 +97,7 @@ export function main() {
}));
it('should reflect user defined `$implicit` property in the context', async(() => {
- const template = `{{ctx.foo}}` +
+ const template = `{{ctx.foo}}` +
``;
fixture = createTestComponent(template);
fixture.componentInstance.context = {$implicit: {foo: 'bra'}};
@@ -105,7 +105,8 @@ export function main() {
}));
it('should reflect context re-binding', async(() => {
- const template = `{{shawshank}}` +
+ const template =
+ `{{shawshank}}` +
``;
fixture = createTestComponent(template);
diff --git a/modules/@angular/compiler/src/jit/compiler_factory.ts b/modules/@angular/compiler/src/jit/compiler_factory.ts
index 129fc693b6..3c4b576e5a 100644
--- a/modules/@angular/compiler/src/jit/compiler_factory.ts
+++ b/modules/@angular/compiler/src/jit/compiler_factory.ts
@@ -109,12 +109,15 @@ export const COMPILER_PROVIDERS: Array|{[k: string]: any}|any[]> =
export class JitCompilerFactory implements CompilerFactory {
private _defaultOptions: CompilerOptions[];
constructor(@Inject(COMPILER_OPTIONS) defaultOptions: CompilerOptions[]) {
- this._defaultOptions = [{
- useDebug: isDevMode(),
- useJit: true,
- defaultEncapsulation: ViewEncapsulation.Emulated,
- missingTranslation: MissingTranslationStrategy.Warning,
- }].concat(defaultOptions);
+ const compilerOptions: CompilerOptions = {
+ useDebug: isDevMode(),
+ useJit: true,
+ defaultEncapsulation: ViewEncapsulation.Emulated,
+ missingTranslation: MissingTranslationStrategy.Warning,
+ enableLegacyTemplate: true,
+ };
+
+ this._defaultOptions = [compilerOptions, ...defaultOptions];
}
createCompiler(options: CompilerOptions[] = []): Compiler {
const opts = _mergeOptions(this._defaultOptions.concat(options));
diff --git a/modules/@angular/compiler/src/ml_parser/html_tags.ts b/modules/@angular/compiler/src/ml_parser/html_tags.ts
index 664a44d80b..aaf3a4d121 100644
--- a/modules/@angular/compiler/src/ml_parser/html_tags.ts
+++ b/modules/@angular/compiler/src/ml_parser/html_tags.ts
@@ -58,7 +58,8 @@ export class HtmlTagDefinition implements TagDefinition {
}
const lcParent = currentParent.toLowerCase();
- return this.requiredParents[lcParent] != true && lcParent != 'template';
+ const isParentTemplate = lcParent === 'template' || currentParent === 'ng-template';
+ return !isParentTemplate && this.requiredParents[lcParent] != true;
}
isClosedByChild(name: string): boolean {
diff --git a/modules/@angular/compiler/src/ml_parser/icu_ast_expander.ts b/modules/@angular/compiler/src/ml_parser/icu_ast_expander.ts
index 1d12779519..d135ee95a3 100644
--- a/modules/@angular/compiler/src/ml_parser/icu_ast_expander.ts
+++ b/modules/@angular/compiler/src/ml_parser/icu_ast_expander.ts
@@ -30,9 +30,9 @@ const PLURAL_CASES: string[] = ['zero', 'one', 'two', 'few', 'many', 'other'];
*
* ```
*
- * zero
- * one
- * more than one
+ * zero
+ * one
+ * more than one
*
* ```
*/
@@ -81,6 +81,7 @@ class _Expander implements html.Visitor {
}
}
+// Plural forms are expanded to `NgPlural` and `NgPluralCase`s
function _expandPluralForm(ast: html.Expansion, errors: ParseError[]): html.Element {
const children = ast.cases.map(c => {
if (PLURAL_CASES.indexOf(c.value) == -1 && !c.value.match(/^=\d+$/)) {
@@ -93,7 +94,7 @@ function _expandPluralForm(ast: html.Expansion, errors: ParseError[]): html.Elem
errors.push(...expansionResult.errors);
return new html.Element(
- `template`, [new html.Attribute('ngPluralCase', `${c.value}`, c.valueSourceSpan)],
+ `ng-template`, [new html.Attribute('ngPluralCase', `${c.value}`, c.valueSourceSpan)],
expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan);
});
const switchAttr = new html.Attribute('[ngPlural]', ast.switchValue, ast.switchValueSourceSpan);
@@ -101,6 +102,7 @@ function _expandPluralForm(ast: html.Expansion, errors: ParseError[]): html.Elem
'ng-container', [switchAttr], children, ast.sourceSpan, ast.sourceSpan, ast.sourceSpan);
}
+// ICU messages (excluding plural form) are expanded to `NgSwitch` and `NgSwitychCase`s
function _expandDefaultForm(ast: html.Expansion, errors: ParseError[]): html.Element {
const children = ast.cases.map(c => {
const expansionResult = expandNodes(c.expression);
@@ -109,12 +111,12 @@ function _expandDefaultForm(ast: html.Expansion, errors: ParseError[]): html.Ele
if (c.value === 'other') {
// other is the default case when no values match
return new html.Element(
- `template`, [new html.Attribute('ngSwitchDefault', '', c.valueSourceSpan)],
+ `ng-template`, [new html.Attribute('ngSwitchDefault', '', c.valueSourceSpan)],
expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan);
}
return new html.Element(
- `template`, [new html.Attribute('ngSwitchCase', `${c.value}`, c.valueSourceSpan)],
+ `ng-template`, [new html.Attribute('ngSwitchCase', `${c.value}`, c.valueSourceSpan)],
expansionResult.nodes, c.sourceSpan, c.sourceSpan, c.sourceSpan);
});
const switchAttr = new html.Attribute('[ngSwitch]', ast.switchValue, ast.switchValueSourceSpan);
diff --git a/modules/@angular/compiler/src/template_parser/template_ast.ts b/modules/@angular/compiler/src/template_parser/template_ast.ts
index a017233bef..8c2a7ef75e 100644
--- a/modules/@angular/compiler/src/template_parser/template_ast.ts
+++ b/modules/@angular/compiler/src/template_parser/template_ast.ts
@@ -108,7 +108,7 @@ export class ReferenceAst implements TemplateAst {
}
/**
- * A variable declaration on a (e.g. `var-someName="someLocalName"`).
+ * A variable declaration on a (e.g. `var-someName="someLocalName"`).
*/
export class VariableAst implements TemplateAst {
constructor(public name: string, public value: string, public sourceSpan: ParseSourceSpan) {}
@@ -135,7 +135,7 @@ export class ElementAst implements TemplateAst {
}
/**
- * A `` element included in an Angular template.
+ * A `` element included in an Angular template.
*/
export class EmbeddedTemplateAst implements TemplateAst {
constructor(
diff --git a/modules/@angular/compiler/src/template_parser/template_parser.ts b/modules/@angular/compiler/src/template_parser/template_parser.ts
index 121f8fa561..df2b9ac9f0 100644
--- a/modules/@angular/compiler/src/template_parser/template_parser.ts
+++ b/modules/@angular/compiler/src/template_parser/template_parser.ts
@@ -54,7 +54,10 @@ const IDENT_PROPERTY_IDX = 9;
// Group 10 = identifier inside ()
const IDENT_EVENT_IDX = 10;
+const NG_TEMPLATE_ELEMENT = 'ng-template';
+// deprecated in 4.x
const TEMPLATE_ELEMENT = 'template';
+// deprecated in 4.x
const TEMPLATE_ATTR = 'template';
const TEMPLATE_ATTR_PREFIX = '*';
const CLASS_ATTR = 'class';
@@ -269,8 +272,9 @@ class TemplateParseVisitor implements html.Visitor {
let hasInlineTemplates = false;
const attrs: AttrAst[] = [];
- const lcElName = splitNsName(nodeName.toLowerCase())[1];
- const isTemplateElement = lcElName == TEMPLATE_ELEMENT;
+ const isTemplateElement = isTemplate(
+ element,
+ (m: string, span: ParseSourceSpan) => this._reportError(m, span, ParseErrorLevel.WARNING));
element.attrs.forEach(attr => {
const hasBinding = this._parseAttr(
@@ -282,6 +286,9 @@ class TemplateParseVisitor implements html.Visitor {
let normalizedName = this._normalizeAttributeName(attr.name);
if (normalizedName == TEMPLATE_ATTR) {
+ this._reportError(
+ `The template attribute is deprecated. Use an ng-template element instead.`,
+ attr.sourceSpan, ParseErrorLevel.WARNING);
templateBindingsSource = attr.value;
} else if (normalizedName.startsWith(TEMPLATE_ATTR_PREFIX)) {
templateBindingsSource = attr.value;
@@ -379,10 +386,9 @@ class TemplateParseVisitor implements html.Visitor {
if (hasInlineTemplates) {
const templateQueryStartIndex = this.contentQueryStartId;
- const templateCssSelector =
- createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
+ const templateSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
const {directives: templateDirectiveMetas} =
- this._parseDirectives(this.selectorMatcher, templateCssSelector);
+ this._parseDirectives(this.selectorMatcher, templateSelector);
const templateBoundDirectivePropNames = new Set();
const templateDirectiveAsts = this._createDirectiveAsts(
true, element.name, templateDirectiveMetas, templateElementOrDirectiveProps, [],
@@ -896,3 +902,19 @@ function isEmptyExpression(ast: AST): boolean {
}
return ast instanceof EmptyExpr;
}
+
+// `template` is deprecated in 4.x
+function isTemplate(
+ el: html.Element, reportDeprecation: (m: string, span: ParseSourceSpan) => void): boolean {
+ const tagNoNs = splitNsName(el.name)[1];
+ // `` is an angular construct and is lower case
+ if (tagNoNs === NG_TEMPLATE_ELEMENT) return true;
+ // `` is HTML and case insensitive
+ if (tagNoNs.toLowerCase() === TEMPLATE_ELEMENT) {
+ reportDeprecation(
+ `The element is deprecated. Use instead`, el.sourceSpan);
+ return true;
+ }
+
+ return false;
+}
diff --git a/modules/@angular/compiler/src/view_compiler/query_binder.ts b/modules/@angular/compiler/src/view_compiler/query_binder.ts
index 6d2e64008b..1a9229b67b 100644
--- a/modules/@angular/compiler/src/view_compiler/query_binder.ts
+++ b/modules/@angular/compiler/src/view_compiler/query_binder.ts
@@ -14,7 +14,7 @@ import {CompileQuery} from './compile_query';
// Note: We can't do this when we create the CompileElements already,
-// as we create embedded views before the elements themselves.
+// as we create embedded views before the elements themselves.
export function bindQueryValues(ce: CompileElement) {
const queriesWithReads: _QueryWithRead[] = [];
diff --git a/modules/@angular/compiler/test/ml_parser/html_parser_spec.ts b/modules/@angular/compiler/test/ml_parser/html_parser_spec.ts
index ba9eb07f6c..6de0084499 100644
--- a/modules/@angular/compiler/test/ml_parser/html_parser_spec.ts
+++ b/modules/@angular/compiler/test/ml_parser/html_parser_spec.ts
@@ -31,10 +31,14 @@ export function main() {
]);
});
- it('should parse text nodes inside template elements', () => {
+ it('should parse text nodes inside elements', () => {
+ // deprecated in 4.0
expect(humanizeDom(parser.parse('a', 'TestComp'))).toEqual([
[html.Element, 'template', 0], [html.Text, 'a', 1]
]);
+ expect(humanizeDom(parser.parse('a', 'TestComp'))).toEqual([
+ [html.Element, 'ng-template', 0], [html.Text, 'a', 1]
+ ]);
});
it('should parse CDATA', () => {
@@ -57,9 +61,11 @@ export function main() {
]);
});
- it('should parse elements inside of template elements', () => {
+ it('should parse elements inside elements', () => {
expect(humanizeDom(parser.parse('', 'TestComp')))
.toEqual([[html.Element, 'template', 0], [html.Element, 'span', 1]]);
+ expect(humanizeDom(parser.parse('', 'TestComp')))
+ .toEqual([[html.Element, 'ng-template', 0], [html.Element, 'span', 1]]);
});
it('should support void elements', () => {
@@ -158,11 +164,16 @@ export function main() {
]);
});
- it('should not add the requiredParent when the parent is a template', () => {
+ it('should not add the requiredParent when the parent is a ', () => {
expect(humanizeDom(parser.parse('
', []))
+ .not.toThrowError();
});
it('should assign references with empty value to components', () => {
@@ -1204,25 +1212,35 @@ Reference "#a" is defined several times ("
]#a>
});
describe('explicit templates', () => {
- it('should create embedded templates for elements', () => {
+ it('should create embedded templates for elements', () => {
expect(humanizeTplAst(parse('', [
]))).toEqual([[EmbeddedTemplateAst]]);
expect(humanizeTplAst(parse('', [
]))).toEqual([[EmbeddedTemplateAst]]);
+ expect(humanizeTplAst(parse('', [
+ ]))).toEqual([[EmbeddedTemplateAst]]);
});
- it('should create embedded templates for elements regardless the namespace',
+ it('should create embedded templates for elements regardless the namespace',
() => {
expect(humanizeTplAst(parse('', []))).toEqual([
[ElementAst, ':svg:svg'],
[EmbeddedTemplateAst],
]);
+ expect(humanizeTplAst(parse('', []))).toEqual([
+ [ElementAst, ':svg:svg'],
+ [EmbeddedTemplateAst],
+ ]);
});
it('should support references via #...', () => {
expect(humanizeTplAst(parse('', []))).toEqual([
[EmbeddedTemplateAst],
- [ReferenceAst, 'a', createIdentifierToken(Identifiers.TemplateRef)]
+ [ReferenceAst, 'a', createIdentifierToken(Identifiers.TemplateRef)],
+ ]);
+ expect(humanizeTplAst(parse('', []))).toEqual([
+ [EmbeddedTemplateAst],
+ [ReferenceAst, 'a', createIdentifierToken(Identifiers.TemplateRef)],
]);
});
@@ -1231,11 +1249,21 @@ Reference "#a" is defined several times ("
', []))).toEqual([
+ [EmbeddedTemplateAst],
+ [ElementAst, 'div'],
+ ]);
});
it('should wrap the element with data-template attribute into an EmbeddedTemplateAST ',
@@ -1403,7 +1438,10 @@ Reference "#a" is defined several times ("
]#a>
describe('project text nodes', () => {
it('should project text nodes with wildcard selector', () => {
expect(humanizeContentProjection(parse('
hello
', [createComp('div', ['*'])])))
- .toEqual([['div', null], ['#text(hello)', 0]]);
+ .toEqual([
+ ['div', null],
+ ['#text(hello)', 0],
+ ]);
});
});
@@ -1415,24 +1453,37 @@ Reference "#a" is defined several times ("
]#a>
});
it('should project elements with css selector', () => {
- expect(humanizeContentProjection(parse('
',
[createComp('div', ['a', 'b']), ngIf])))
- .toEqual([['div', null], ['template', 1], ['a', null]]);
+ .toEqual([
+ ['div', null],
+ ['template', 1],
+ ['a', null],
+ ]);
});
});
@@ -1539,13 +1599,17 @@ Reference "#a" is defined several times ("
]#a>
` element cannot have content. ("[ERROR ->]content"): TestComp@0:0`);
});
- it('should treat *attr on a template element as valid',
- () => { expect(() => parse('', [])).not.toThrowError(); });
+ it('should treat *attr on a template element as valid', () => {
+ expect(() => parse('', [])).not.toThrowError();
+ expect(() => parse('', [])).not.toThrowError();
+ });
- it('should treat template attribute on a template element as valid',
- () => { expect(() => parse('', [])).not.toThrowError(); });
+ it('should treat template attribute on a template element as valid', () => {
+ expect(() => parse('', [])).not.toThrowError();
+ expect(() => parse('', [])).not.toThrowError();
+ });
- it('should report when mutliple *attrs are used on the same element', () => {
+ it('should report when multiple *attrs are used on the same element', () => {
expect(() => parse('
', [])).toThrowError(`Template parse errors:
Can't have multiple template bindings on one element. Use only one attribute named 'template' or prefixed with * ("
]*ngFor>"): TestComp@0:11`);
});
@@ -1630,11 +1694,18 @@ Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("
parse('', [dirA]))
.toThrowError(`Template parse errors:
Event binding e not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("](e)="f">"): TestComp@0:18
Components on an embedded template: DirA ("[ERROR ->]"): TestComp@0:0
Property binding a not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("[ERROR ->]"): TestComp@0:0`);
+
+ expect(() => parse('', [dirA]))
+ .toThrowError(`Template parse errors:
+Event binding e not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("](e)="f">"): TestComp@0:21
+Components on an embedded template: DirA ("[ERROR ->]"): TestComp@0:0
+Property binding a not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations". ("[ERROR ->]"): TestComp@0:0`);
});
it('should not allow components or element bindings on inline embedded templates', () => {
@@ -1745,7 +1816,8 @@ Property binding a not used by any directive on an embedded template. Make sure
it('should support embedded template', () => {
expect(humanizeTplAstSourceSpans(parse('', [
]))).toEqual([[EmbeddedTemplateAst, '']]);
-
+ expect(humanizeTplAstSourceSpans(parse('', [
+ ]))).toEqual([[EmbeddedTemplateAst, '']]);
});
it('should support element and attributes', () => {
@@ -1762,8 +1834,14 @@ Property binding a not used by any directive on an embedded template. Make sure
it('should support variables', () => {
expect(humanizeTplAstSourceSpans(parse('', []))).toEqual([
- [EmbeddedTemplateAst, ''], [VariableAst, 'a', 'b', 'let-a="b"']
+ [EmbeddedTemplateAst, ''],
+ [VariableAst, 'a', 'b', 'let-a="b"'],
]);
+ expect(humanizeTplAstSourceSpans(parse('', [])))
+ .toEqual([
+ [EmbeddedTemplateAst, ''],
+ [VariableAst, 'a', 'b', 'let-a="b"'],
+ ]);
});
it('should support events', () => {
@@ -1917,8 +1995,8 @@ The pipe 'test' could not be found ("{{[ERROR ->]a | test}}"): TestComp@0:2`);
it('should expand plural messages', () => {
const shortForm = '{ count, plural, =0 {small} many {big} }';
const expandedForm = '' +
- 'small' +
- 'big' +
+ 'small' +
+ 'big' +
'';
expect(humanizeTplAst(parse(shortForm, []))).toEqual(humanizeTplAst(parse(expandedForm, [
@@ -1928,8 +2006,8 @@ The pipe 'test' could not be found ("{{[ERROR ->]a | test}}"): TestComp@0:2`);
it('should expand select messages', () => {
const shortForm = '{ sex, select, female {foo} other {bar} }';
const expandedForm = '' +
- 'foo' +
- 'bar' +
+ 'foo' +
+ 'bar' +
'';
expect(humanizeTplAst(parse(shortForm, []))).toEqual(humanizeTplAst(parse(expandedForm, [
@@ -2057,10 +2135,6 @@ class TemplateHumanizer implements TemplateAstVisitor {
}
}
-function sourceInfo(ast: TemplateAst): string {
- return `${ast.sourceSpan}: ${ast.sourceSpan.start}`;
-}
-
function humanizeContentProjection(templateAsts: TemplateAst[]): any[] {
const humanizer = new TemplateContentProjectionHumanizer();
templateVisitAll(humanizer, templateAsts);
diff --git a/modules/@angular/core/src/linker/template_ref.ts b/modules/@angular/core/src/linker/template_ref.ts
index 649af6da3d..26f3cdb93e 100644
--- a/modules/@angular/core/src/linker/template_ref.ts
+++ b/modules/@angular/core/src/linker/template_ref.ts
@@ -14,10 +14,10 @@ import {EmbeddedViewRef} from './view_ref';
/**
* Represents an Embedded Template that can be used to instantiate Embedded Views.
*
- * You can access a `TemplateRef`, in two ways. Via a directive placed on a `` element (or
- * directive prefixed with `*`) and have the `TemplateRef` for this Embedded View injected into the
- * constructor of the directive using the `TemplateRef` Token. Alternatively you can query for the
- * `TemplateRef` from a Component or a Directive via {@link Query}.
+ * You can access a `TemplateRef`, in two ways. Via a directive placed on a `` element
+ * (or directive prefixed with `*`) and have the `TemplateRef` for this Embedded View injected into
+ * the constructor of the directive using the `TemplateRef` Token. Alternatively you can query for
+ * the `TemplateRef` from a Component or a Directive via {@link Query}.
*
* To instantiate Embedded Views based on a Template, use
* {@link ViewContainerRef#createEmbeddedView}, which will create the View and attach it to the
diff --git a/modules/@angular/core/src/linker/view_ref.ts b/modules/@angular/core/src/linker/view_ref.ts
index f546417044..f296191899 100644
--- a/modules/@angular/core/src/linker/view_ref.ts
+++ b/modules/@angular/core/src/linker/view_ref.ts
@@ -57,7 +57,7 @@ export abstract class ViewRef extends ChangeDetectorRef {
* ```
* Count: {{items.length}}
*
diff --git a/modules/@angular/core/src/linker/view_type.ts b/modules/@angular/core/src/linker/view_type.ts
index bce9a9ac59..8d9179f129 100644
--- a/modules/@angular/core/src/linker/view_type.ts
+++ b/modules/@angular/core/src/linker/view_type.ts
@@ -10,10 +10,8 @@ export enum ViewType {
// A view that contains the host element with bound component directive.
// Contains a COMPONENT view
HOST,
- // The view of the component
- // Can contain 0 to n EMBEDDED views
+ // The view of the component can contain 0 to n EMBEDDED views
COMPONENT,
- // A view that is embedded into another View via a element
- // inside of a COMPONENT view
+ // A view is embedded into another View via a element inside of a COMPONENT view
EMBEDDED
}
diff --git a/modules/@angular/core/test/application_ref_spec.ts b/modules/@angular/core/test/application_ref_spec.ts
index 34c4fe2c2e..ebe21cd52e 100644
--- a/modules/@angular/core/test/application_ref_spec.ts
+++ b/modules/@angular/core/test/application_ref_spec.ts
@@ -286,7 +286,7 @@ export function main() {
vc: ViewContainerRef;
}
- @Component({template: 'Dynamic content'})
+ @Component({template: 'Dynamic content'})
class EmbeddedViewComp {
@ViewChild(TemplateRef)
tplRef: TemplateRef