内联模板包含组件 [英] Component transclude with inline template

查看:89
本文介绍了内联模板包含组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Angular 2-rc3,并且有一个Component,我想应用包含,只是有些不同.这是我的组件:

I'm using Angular 2-rc3 and have a Component and I want to apply transclusion, just in a bit of a different way. Here's my 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>

如您所见,我正在尝试定义将由组件使用的内联模板.现在,这太糟糕了.首先,一个数据绑定异常说can't read property 'make' of undefined.它试图从周围的组件而不是MyListComponent读取item.make.但是,即使我暂时暂时将其禁用:

As you can see, I'm trying to define an inline template that will be used by my component. Now this goes horribly wrong. First off, a databinding exception saying it can't read property 'make' of undefined. It's trying to read item.make off of my surrounding component, not of the MyListComponent. But even if I temporarily disable this for now:

<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中使用的模板,它只是绑定了元素,它们最终与最后一个项目相关联.

So Angular doesn't actually copy the template for use within the *ngFor, it just binds the elements and they end up associated with the last item.

如何使它正常工作?

我在AngularJS中遇到了同样的问题,其中 petebacondarwin发布了一个解决方案通过编译操作DOM ,这很棒.通过在组件中注入ElementRef,我也可以在Angular 2中使用此选项,但是!一个很大的不同是AngularJS中的compile在数据绑定之前就消失了,这意味着在模板中使用{{item.make}}没有问题.在Angular 2中,这似乎是行不通的,因为{{item}}是预先解析的.那么解决这个问题的最佳方法是什么?使用稍微不同的表示法[[item]]和字符串替换整个内容似乎不是最优雅的方法...

I had the same issue with AngularJS, where petebacondarwin posted a solution to manipulate the DOM through compile, which was great. I have this option with Angular 2 as well by injecting ElementRef in my component, but! One big difference is that compile in AngularJS went off before databinding, meaning there were no problems using {{item.make}} in the template. With Angular 2, this seems to be a no-go since {{item}} is being parsed before-hand. So what's the best way to go about this? Using the slightly different notation [[item]] and string replacing the entire thing doesn't seem the most elegant way...

提前谢谢!

//这是一个重现此问题的 Plnkr .

// Here's a Plnkr that reproduces the problem.

推荐答案

要阐明ngForTemplate方法:

(从Angular 4起,该元素现在称为<ng-template>.)

(As of Angular 4 the element is now called <ng-template>.)

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

<li>移至app.component html,并且该组件上的<template>具有特殊的'let-'属性,该属性在内部引用了迭代变量组件:

The <li> is moved to the app.component html, and the <template> on this component has a special 'let-' attribute which references the iterated variable in the inner component:

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

  • 内部组件也具有<template>,并使用ngFor的变体,如下所示:

  • The inner component has <template> as well and uses a variant of ngFor like so:

    <ul>
        <template #items ngFor [ngForOf]="data" [ngForTemplate]="tmpl">
            -- insert template here --
        </template>
    </ul>
    

  • 分配给ngForTemplate属性的'tmpl'变量需要在组件代码中获取:

  • The 'tmpl' variable assigned to the ngForTemplate attribute needs to be fetched in the component code:

    export class MyListComponent {
        @Input() data: any[];
        @ContentChild(TemplateRef) tmpl: TemplateRef;
    }
    

  • @ContentChild和TemplateRef是角位,因此需要导入

  • @ContentChild and TemplateRef are angular bits, so need to be imported

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

  • 在以下 plnkr 中查看带有这些更改的plunkr的分支.

    See the fork of your plunkr with these changes in here plnkr.

    对于您所陈述的问题,这不是最令人满意的解决方案,因为您要将数据传递到列表中,因此外部最好还有ngFor.另外,其他内容(文字'-在此处插入模板-')被删除,因此您想显示它也必须在外部模板上.

    This isn't the most satisfactory solution for your stated problem, since you're passing the data in to the list you might as well have the ngFor on the outer. Plus, the additional content (the literal '-- insert template here --') gets dropped, so it you wanted to display that it must be on the outer template as well.

    我看到在内部组件中提供迭代的地方(例如,通过服务调用)可能很有用,并且也许可以对代码中的模板进行一些操作.

    I can see it might be useful where the iteration is provided within the inner component (say from a service call), and maybe to do some manipulation of the template in code.

    这篇关于内联模板包含组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆