Skip to content

Commit

Permalink
feat(compiler): set enableLegacyTemplate to false by default (#18756)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: the compiler option `enableLegacyTemplate` is now disabled by default as the `<template>` element has been deprecated since v4. Use `<ng-template>` instead. The option `enableLegacyTemplate` and the `<template>` element will both be removed in Angular v6.
PR Close #18756
  • Loading branch information
ocombe authored and jasonaden committed Sep 1, 2017
1 parent fcadeb2 commit 56238fe
Show file tree
Hide file tree
Showing 22 changed files with 49 additions and 82 deletions.
12 changes: 6 additions & 6 deletions aio/content/examples/ngcontainer/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,22 @@ <h4>#3 &lt;ng-container&gt; and &lt;p&gt;</h4>
</div>

<div>
The <code>hero.id</code> in the &lt;template *ngIf&gt; disappears:
The <code>hero.id</code> in the &lt;ng-template *ngIf&gt; disappears:
<p>
<template *ngIf="showId">
<ng-template *ngIf="showId">
Id: ({{hero.id}})
</template>
</ng-template>
Name: {{hero.name}}
</p>
</div>

<div>
The <code>hero.id</code> in the &lt;template [ngIf]&gt;
The <code>hero.id</code> in the &lt;ng-template [ngIf]&gt;
is unaffected by the <span>p-span</span> CSS:
<p>
<template [ngIf]="showId">
<ng-template [ngIf]="showId">
Id: ({{hero.id}})
</template>
</ng-template>
Name: {{hero.name}}
</p>
</div>
Expand Down
4 changes: 2 additions & 2 deletions aio/content/examples/structural-directives/e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ describe('Structural Directives', function () {
expect(allLis.get(0).getText()).toEqual('Mr. Nice');
});

it('ngSwitch have three <happy-hero> instances', function () {
it('ngSwitch have two <happy-hero> instances', function () {
const happyHeroEls = element.all(by.tagName('happy-hero'));
expect(happyHeroEls.count()).toEqual(3);
expect(happyHeroEls.count()).toEqual(2);
});

it('should toggle *ngIf="hero" with a button', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,6 @@ <h4>NgIf with template</h4>
</ng-template>
<!-- #enddocregion ngif-template -->

<p>template attribute</p>
<!-- #docregion ngif-template-attr -->
<div template="ngIf hero">{{hero.name}}</div>
<!-- #enddocregion ngif-template-attr -->

<hr>

<h2 id="ng-container">&lt;ng-container&gt;</h2>
Expand Down Expand Up @@ -131,14 +126,7 @@ <h2 id="ngFor">NgFor</h2>
</div>

<!--#enddocregion inside-ngfor -->
<p class="code">&lt;div template="ngFor let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd"&gt;</p>
<!--#docregion inside-ngfor -->
<div template="ngFor let hero of heroes; let i=index; let odd=odd; trackBy: trackById" [class.odd]="odd">
({{i}}) {{hero.name}}
</div>

<!--#enddocregion inside-ngfor -->
<p class="code">&lt;template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById"&gt;</p>
<p class="code">&lt;ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById"/&gt;</p>
<!--#docregion inside-ngfor -->
<ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" [ngForTrackBy]="trackById">
<div [class.odd]="odd">({{i}}) {{hero.name}}</div>
Expand Down Expand Up @@ -169,16 +157,6 @@ <h4>NgSwitch</h4>
</div>
<!-- #enddocregion built-in, ngswitch -->

<h4>NgSwitch with <i>template</i> attribute</h4>
<!-- #docregion ngswitch-template-attr -->
<div [ngSwitch]="hero?.emotion">
<happy-hero template="ngSwitchCase 'happy'" [hero]="hero"></happy-hero>
<sad-hero template="ngSwitchCase 'sad'" [hero]="hero"></sad-hero>
<confused-hero template="ngSwitchCase 'confused'" [hero]="hero"></confused-hero>
<unknown-hero template="ngSwitchDefault" [hero]="hero"></unknown-hero>
</div>
<!-- #enddocregion ngswitch-template-attr -->

<h4>NgSwitch with &lt;ng-template&gt;</h4>
<!-- #docregion ngswitch-template -->
<div [ngSwitch]="hero?.emotion">
Expand All @@ -199,7 +177,7 @@ <h4>NgSwitch with &lt;ng-template&gt;</h4>

<hr>

<h2>&lt;template&gt;</h2>
<h2>&lt;ng-template&gt;</h2>
<!-- #docregion template-tag -->
<p>Hip!</p>
<ng-template>
Expand Down Expand Up @@ -238,13 +216,13 @@ <h4>UnlessDirective with template</h4>
<p *myUnless="condition">Show this sentence unless the condition is true.</p>
<!-- #enddocregion myUnless-1 -->

<p template="myUnless condition" class="code unless">
(A) &lt;p template="myUnless condition" class="code unless"&gt;
<p *myUnless="condition" class="code unless">
(A) &lt;p *myUnless="condition" class="code unless"&gt;
</p>

<ng-template [myUnless]="condition">
<p class="code unless">
(A) &lt;template [myUnless]="condition"&gt;
(A) &lt;ng-template [myUnless]="condition"&gt;
</p>
</ng-template>

Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
* ### Syntax
*
* - `<div *myUnless="condition">...</div>`
* - `<div template="myUnless condition">...</div>`
* - `<template [myUnless]="condition"><div>...</div></template>`
* - `<ng-template [myUnless]="condition"><div>...</div></ng-template>`
*
// #docregion no-docs
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ <h3>

<p>Template input variable expression context (let hero)</p>
<!-- template hides the following; plenty of examples later -->
<template>
<ng-template>
<!-- #docregion context-var -->
<div *ngFor="let hero of heroes">{{hero.name}}</div>
<!-- #enddocregion context-var -->
</template>
</ng-template>

<p>Template reference variable expression context (#heroInput)</p>
<div (keyup)="0" class="context">
Expand Down
33 changes: 6 additions & 27 deletions aio/content/guide/structural-directives.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,17 +208,7 @@ Here is `*ngIf` displaying the hero's name if `hero` exists.


The asterisk is "syntactic sugar" for something a bit more complicated.
Internally, Angular desugars it in two stages.
First, it translates the `*ngIf="..."` into a template _attribute_, `template="ngIf ..."`,&nbsp; like this.


<code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif-template-attr)" region="ngif-template-attr">

</code-example>



Then it translates the template _attribute_ into a `<ng-template>` _element_, wrapped around the host element, like this.
Internally, Angular translates the `*ngIf` _attribute_ into a `<ng-template>` _element_, wrapped around the host element, like this.


<code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngif-template)" region="ngif-template">
Expand All @@ -230,8 +220,7 @@ Then it translates the template _attribute_ into a `<ng-template>` _element_, wr
* The `*ngIf` directive moved to the `<ng-template>` element where it became a property binding,`[ngIf]`.
* The rest of the `<div>`, including its class attribute, moved inside the `<ng-template>` element.

None of these forms are actually rendered.
Only the finished product ends up in the DOM.
The first form is not actually rendered, only the finished product ends up in the DOM.


<figure>
Expand All @@ -252,10 +241,9 @@ The [`NgFor`](guide/structural-directives#ngFor) and [`NgSwitch...`](guide/struc

## Inside _*ngFor_

Angular transforms the `*ngFor` in similar fashion from asterisk (*) syntax through
template _attribute_ to `<ng-template>` _element_.
Angular transforms the `*ngFor` in similar fashion from asterisk (*) syntax to `<ng-template>` _element_.

Here's a full-featured application of `NgFor`, written all three ways:
Here's a full-featured application of `NgFor`, written both ways:


<code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (inside-ngfor)" region="inside-ngfor">
Expand Down Expand Up @@ -415,16 +403,7 @@ The `<unknown-hero>` is the host element for the `*ngSwitchDefault`.


As with other structural directives, the `NgSwitchCase` and `NgSwitchDefault`
can be desugared into the template _attribute_ form.


<code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngswitch-template-attr)" region="ngswitch-template-attr">

</code-example>



That, in turn, can be desugared into the `<ng-template>` element form.
can be desugared into the `<ng-template>` element form.


<code-example path="structural-directives/src/app/app.component.html" linenums="false" title="src/app/app.component.html (ngswitch-template)" region="ngswitch-template">
Expand All @@ -438,7 +417,7 @@ That, in turn, can be desugared into the `<ng-template>` element form.

## Prefer the asterisk (*) syntax.

The asterisk (*) syntax is more clear than the other desugared forms.
The asterisk (*) syntax is more clear than the desugared form.
Use [&lt;ng-container&gt;](guide/structural-directives#ng-container) when there's no single element
to host the directive.

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified aio/content/images/guide/structural-directives/hero-div-in-dom.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified aio/content/images/guide/structural-directives/template-rendering.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion packages/common/src/directives/ng_for_of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ export class NgForOfContext<T> {
* ### Syntax
*
* - `<li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>`
* - `<li template="ngFor let item of items; index as i; trackBy: trackByFn">...</li>`
*
* With `<ng-template>` element:
*
Expand Down
1 change: 0 additions & 1 deletion packages/common/src/directives/ng_if.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '
*
* Simple form:
* - `<div *ngIf="condition">...</div>`
* - `<div template="ngIf condition">...</div>`
* - `<ng-template [ngIf]="condition"><div>...</div></ng-template>`
*
* Form with an else block:
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-cli/src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export class CodeGenerator {
translations: transContent,
i18nFormat: cliOptions.i18nFormat || undefined,
locale: cliOptions.locale || undefined, missingTranslation,
enableLegacyTemplate: options.enableLegacyTemplate !== false,
enableLegacyTemplate: options.enableLegacyTemplate === true,
enableSummariesForJit: options.enableSummariesForJit !== false,
preserveWhitespaces: options.preserveWhitespaces,
});
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-cli/src/transformers/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export interface CompilerOptions extends ts.CompilerOptions {
// Print extra information while running the compiler
trace?: boolean;

// Whether to enable support for <template> and the template attribute (true by default)
// Whether to enable support for <template> and the template attribute (false by default)
enableLegacyTemplate?: boolean;

// Whether to enable lowering expressions lambdas and expressions in a reference value
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/aot/compiler_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export function createAotCompiler(compilerHost: AotCompilerHost, options: AotCom
const config = new CompilerConfig({
defaultEncapsulation: ViewEncapsulation.Emulated,
useJit: false,
enableLegacyTemplate: options.enableLegacyTemplate !== false,
enableLegacyTemplate: options.enableLegacyTemplate === true,
missingTranslation: options.missingTranslation,
preserveWhitespaces: options.preserveWhitespaces,
});
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class CompilerConfig {
this.useJit = !!useJit;
this.jitDevMode = !!jitDevMode;
this.missingTranslation = missingTranslation || null;
this.enableLegacyTemplate = enableLegacyTemplate !== false;
this.enableLegacyTemplate = enableLegacyTemplate === true;
this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces));
}
}
Expand Down
19 changes: 12 additions & 7 deletions packages/compiler/test/template_parser/template_parser_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,19 @@ export function main() {
schemas?: SchemaMetadata[], preserveWhitespaces?: boolean) => TemplateAst[];
let console: ArrayConsole;

function commonBeforeEach() {
function configureCompiler() {
console = new ArrayConsole();
beforeEach(() => {
console = new ArrayConsole();
TestBed.configureCompiler({
providers: [
{provide: Console, useValue: console},
{provide: CompilerConfig, useValue: new CompilerConfig({enableLegacyTemplate: true})}
],
});
});
}

function commonBeforeEach() {
beforeEach(inject([TemplateParser], (parser: TemplateParser) => {
const someAnimation = new CompileAnimationEntryMetadata('someAnimation', []);
const someTemplate = compileTemplateMetadata({animations: [someAnimation]});
Expand Down Expand Up @@ -286,6 +289,7 @@ export function main() {
});
});

configureCompiler();
commonBeforeEach();

describe('security context', () => {
Expand Down Expand Up @@ -318,6 +322,7 @@ export function main() {
TestBed.configureCompiler({providers: [TEST_COMPILER_PROVIDERS, MOCK_SCHEMA_REGISTRY]});
});

configureCompiler();
commonBeforeEach();

describe('parse', () => {
Expand Down Expand Up @@ -2129,13 +2134,13 @@ The pipe 'test' could not be found ("{{[ERROR ->]a | test}}"): TestComp@0:2`);

});

describe('Template Parser - opt-out `<template>` support', () => {
describe('Template Parser - `<template>` support disabled by default', () => {
beforeEach(() => {
TestBed.configureCompiler({
providers: [{
provide: CompilerConfig,
useValue: new CompilerConfig({enableLegacyTemplate: false}),
}],
providers: [
{provide: Console, useValue: console},
{provide: CompilerConfig, useValue: new CompilerConfig()}
],
});
});

Expand Down
10 changes: 9 additions & 1 deletion packages/core/test/linker/integration_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import {CommonModule} from '@angular/common';
import {CompilerConfig} from '@angular/compiler';
import {Compiler, ComponentFactory, ComponentRef, ErrorHandler, EventEmitter, Host, Inject, Injectable, InjectionToken, Injector, NO_ERRORS_SCHEMA, NgModule, NgModuleRef, OnDestroy, SkipSelf, ViewRef} from '@angular/core';
import {ChangeDetectionStrategy, ChangeDetectorRef, PipeTransform} from '@angular/core/src/change_detection/change_detection';
import {getDebugContext} from '@angular/core/src/errors';
Expand Down Expand Up @@ -37,7 +38,14 @@ export function main() {
function declareTests({useJit}: {useJit: boolean}) {
describe('integration tests', function() {

beforeEach(() => { TestBed.configureCompiler({useJit}); });
beforeEach(() => {
TestBed.configureCompiler({
useJit,
providers: [
{provide: CompilerConfig, useValue: new CompilerConfig({enableLegacyTemplate: true})}
]
});
});

describe('react to record changes', function() {
it('should consume text node changes', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/platform-browser-dynamic/src/compiler_factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class JitCompilerFactory implements CompilerFactory {
useJit: true,
defaultEncapsulation: ViewEncapsulation.Emulated,
missingTranslation: MissingTranslationStrategy.Warning,
enableLegacyTemplate: true,
enableLegacyTemplate: false,
};

this._defaultOptions = [compilerOptions, ...defaultOptions];
Expand Down
2 changes: 1 addition & 1 deletion packages/tsc-wrapped/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ interface Options extends ts.CompilerOptions {
// Print extra information while running the compiler
trace?: boolean;

// Whether to enable support for <template> and the template attribute (true by default)
// Whether to enable support for <template> and the template attribute (false by default)
enableLegacyTemplate?: boolean;

// Whether to generate .ngsummary.ts files that allow to use AOTed artifacts
Expand Down

0 comments on commit 56238fe

Please sign in to comment.