user3794166
user3794166

Reputation:

Why can't I use <template> as an angular2 component template?

Update

Apparently when using <template> the reading of innerHTML will return all attributes in lower case. Angular2 will not understand ngfor or ngif as of this beta 9 version and throws error. <script> is treated as a text fragment rather than DOM, which means attributes stay as they are.

Here: https://groups.google.com/forum/#!topic/angular/yz-XdYV2vYw

Originial

Taking the following html and angular2 beta 9 component:

HTML CODE

<my-page>Loading...</my-page>

<script type="text/html" id="my-component-template1">
    <select [(ngModel)]="SelectedType">
        <option *ngFor="#someType of MyTypes" [selected]="SelectedType == someType" [value]="someType">{{someType}}</option>
    </select>
</script>

<template id="my-component-template2">
    <select [(ngModel)]="SelectedType">
        <option *ngFor="#someType of MyTypes" [selected]="SelectedType == someType" [value]="someType">{{someType}}</option>
    </select>
</template>

JS CODE

    var myComponent =
        ng.core.Component({
            selector: 'my-page',

            //complains if i use #my-component-template2
            template: document.querySelector('#my-component-template1').innerHTML 
        })
        .Class({
            constructor: function () {
                var self = this;

                self.MyTypes = ['first', 'second'];
                self.SelectedType = self.MyTypes[0];
            }
        });

    document.addEventListener('DOMContentLoaded', function () {
        ng.platform.browser.bootstrap(myComponent);
    });

If i use my-component-template1 it works fine, but if i choose my-component-template2 it complains that ngModel and ngForOf are not a known native properties.

I tested a div as a template and apparently that won't work either with the same errors. So question is, why is it breaking if the template is part of the DOM? Furthermore, I really don't want to use the script text/html hack. Assuming this is why <template> was added in html5 specification. Why is this happening and how can i fix it?

Upvotes: 2

Views: 6158

Answers (2)

Cosmin Ababei
Cosmin Ababei

Reputation: 7072

The <template> tag is only used by Angular 2 structural directives (like the built-in ngIf, ngFor, ngSwitch, etc) - its use is somehow similar with the html5 specification since it defines content which is stored for subsequent use.

The * in front of a structural directive is just syntactic sugar which allows us to skip the <template> tag and focus directly on the HTML element that we are including, excluding, or repeating - you can read more about it here.

An example from Angular 2 docs which showcases this:

<!-- Examples (A) and (B) are the same -->
<!-- (A) *ngIf paragraph -->
<p *ngIf="condition">
  Our heroes are true!
</p>

<!-- (B) [ngIf] with template -->
<template [ngIf]="condition">
  <p>
    Our heroes are true!
  </p>
</template>

At the moment, I'm not sure if there's a way of defining inline Angular 2 HTML templates like there's in AngularJS 1. Your hack, as you put it, seems to do its job.

Upvotes: 2

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657731

Angular handles <template> tags itself and doesn't simply add them to the DOM. If you inject TemplateRef into the constructor of your component you should get a reference to the template.

class MyComponent {
  constructor(private tmplRef:TemplateRef) {

  }
}

Upvotes: 0

Related Questions