angular - 使用内联模板嵌入组件

标签 angular angular2-components

我正在使用 Angular 2-rc3 并有一个 Component,我想应用嵌入,只是方式有点不同。这是我的组件:

import { Component, Input } from '@angular/core';

@Component({
    selector: 'my-list',
    template: `<ul>
        <li *ngFor="let item of data">
            -- insert template here --
            <ng-content></ng-content>
        </li>
    </ul>`
})
export class MyListComponent {
    @Input() data: any[];
}

我是这样使用它的:

<my-list [data]="cars">
    <div>{{item.make | uppercase}}</div>
</my-list>

如您所见,我正在尝试定义一个将由我的组件使用的内联模板。现在这是非常错误的。首先,一个数据绑定(bind)异常表明它 can't read property 'make' of undefined。它试图从我周围的组件中读取 item.make,而不是从 MyListComponent 中读取。但即使我现在暂时禁用它:

<my-list [data]="cars">
    <div>{item.make | uppercase}</div>
</my-list>

那么第二个问题出现了:

-- insert template here --
-- insert template here --
-- insert template here --
-- insert template here --
{item.make | uppercase}

因此 Angular 实际上并没有复制模板以在 *ngFor 中使用,它只是绑定(bind)元素并且它们最终与最后一个项目相关联。

我如何让它工作?

我在使用 AngularJS 时遇到了同样的问题,其中 petebacondarwin posted a solution to manipulate the DOM through compile ,这很棒。通过在我的组件中注入(inject) ElementRef,我在 Angular 2 中也有这个选项,但是!一个很大的区别是 AngularJS 中的 compile 在数据绑定(bind)之前关闭,这意味着在模板中使用 {{item.make}} 没有问题。对于 Angular 2,这似乎是行不通的,因为 {{item}} 是预先解析的。那么最好的方法是什么?使用略有不同的符号 [[item]] 和字符串替换整个东西似乎不是最优雅的方式......

提前致谢!

//编辑:这是一个Plnkr重现问题。

最佳答案

拼出ngForTemplate方法:

(从 Angular 4 开始,该元素现在称为 <ng-template>。)

  1. 使用 <template>在外部和内部组件中标记,而不是 <ng-content> .

  2. <li>移动到 app.component html,<template>此组件上有一个特殊的 'let-' 属性,它引用内部组件中的迭代变量:

    <my-list [data]="cars">
      <template let-item>
        <li>
          <div>{{item.make | uppercase}}</div>
        </li>
      </template>
    </my-list>
    
  3. 内部组件有<template>以及像这样使用 ngFor 的变体:

    <ul>
        <template #items ngFor [ngForOf]="data" [ngForTemplate]="tmpl">
            -- insert template here --
        </template>
    </ul>
    
  4. 需要在组件代码中获取分配给 ngForTemplate 属性的“tmpl”变量:

    export class MyListComponent {
        @Input() data: any[];
        @ContentChild(TemplateRef) tmpl: TemplateRef;
    }
    
  5. @ContentChild 和TemplateRef 是 Angular 位,所以需要导入

    import { Component, Input, ContentChild, TemplateRef } from '@angular/core';
    

请在此处查看包含这些更改的 plunkr 的分支 plnkr .

对于您所述的问题,这不是最令人满意的解决方案,因为您将数据传递到列表中,所以您最好在外部使用 ngFor。此外,附加内容(文字“-- 在此处插入模板 --”)被删除,因此您想要显示它也必须在外部模板上。

我可以看到在内部组件中提供迭代(比如从服务调用)并且可能在代码中对模板进行一些操作时它可能很有用。

关于angular - 使用内联模板嵌入组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38010627/

相关文章:

javascript - 不带管道的过滤器 Angular 6 : overriding problem

html - 我无法更改元素的设计

Angular2 - 表单中的自定义指令不当行为

javascript - Express Session 属性区分浏览器和 Postman

javascript - 多行字符串的 WebStorm 突出显示

javascript - 根据单击的标题在 Angular4 中排序

typescript - 角度2 : Reusing common component twice on the same page

Angular4图像上传到s3存储桶并将响应存储到全局变量中,可以访问其他方法/函数

angularjs - 在 Jquery 插件模板中绑定(bind) Angular2 组件

angular - 如何降级用 angular2 编写的自定义管道以用于 angular 1.5?