【问题标题】:Why can't I use <template> as an angular2 component template?为什么我不能使用 <template> 作为 angular2 组件模板?
【发布时间】:2016-03-22 22:23:38
【问题描述】:

更新

显然,当使用&lt;template&gt; 时,innerHTML 的读数将返回小写的所有属性。从这个 beta 9 版本开始,Angular2 将无法理解 ngforngif 并引发错误。 &lt;script&gt; 被视为文本片段而不是 DOM,这意味着属性保持原样。

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

原创

采用以下html和angular2 beta 9组件:

HTML 代码

<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 代码

    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);
    });

如果我使用my-component-template1,它可以正常工作,但如果我选择my-component-template2,它会抱怨ngModelngForOf 不是已知的本机属性。

我测试了一个div 作为模板,显然这也不会出现同样的错误。所以问题是,如果模板是 DOM 的一部分,为什么会破坏?此外,我真的不想使用script text/html hack。假设这就是在 html5 规范中添加 &lt;template&gt; 的原因。为什么会发生这种情况,我该如何解决?

【问题讨论】:

    标签: javascript templates angular angular2-template angular2-directives


    【解决方案1】:

    &lt;template&gt; 标签仅由 Angular 2 structural directives 使用(如内置的 ngIf、ngFor、ngSwitch 等) - 它的使用在某种程度上与 html5 specification 相似,因为它定义了存储以供后续使用的内容。

    结构指令前面的* 只是语法糖,它允许我们跳过&lt;template&gt; 标记并直接关注我们包含、排除或重复的HTML 元素 - 您可以阅读更多关于它的信息here.

    Angular 2 文档中的一个例子展示了这一点:

    <!-- 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>
    

    目前,我不确定是否有像 AngularJS 1 中那样定义内联 Angular 2 HTML 模板的方法。正如您所说,您的 hack 似乎可以完成它的工作。

    【讨论】:

    • 每个 hack 都有它的工作,但我们应该遵循标准,尽量不要随意破解。同时,我的谷歌讨论揭示了这个问题。检查我的更新。
    【解决方案2】:

    Angular 自己处理 &lt;template&gt; 标签,而不是简单地将它们添加到 DOM。如果你将TemplateRef 注入到组件的构造函数中,你应该得到对模板的引用。

    class MyComponent {
      constructor(private tmplRef:TemplateRef) {
    
      }
    }
    

    【讨论】:

    • 我没有使用 ES6,那么这在现有的 JS 中如何翻译? Template 是在构造函数之前执行的组件定义的必填字段。
    • 这对于 ES6 或 TS 是一样的。不确定“Template 是必填字段”是什么意思。如果你指的是@Component(select: 'xxx', template: 'yyy')装饰器的template参数,那么这个参数和&lt;template&gt;标签的使用完全没有关系。 TemplateRef 是 DI 的一个类型和一个令牌,它导致获得对 &lt;template&gt; 元素的引用,如 @Query()
    • 我的问题与注入无关,而是使用&lt;template&gt; 作为组件的实际模板。获取对它的引用不是问题,但解析是。检查我的更新。
    • 实际用例是什么?你试图完成什么。我不明白您所说的“作为组件的实际模板”是什么意思。
    • 使用&lt;template&gt; 作为组件的模板是不应该的。正如我已经提到的,组件需要的模板与&lt;template&gt; 标签无关。名称相等是偶然的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    相关资源
    最近更新 更多