Angular2本地组件/模板重用

时间:2016-04-14 01:16:45

标签: angular angular2-template

我正在编写一些Angular2模板,这些模板具有不同容器的重复部分。在这种情况下,如果事物已分组并且启用了多节模式,则视图可能会更改。请原谅长长的例子,但是这样的话:

<template [ngIf]="isCategoryGrouped">
    <div *ngFor="#categories of categories">
        <div>{{ categories.category.name }}</div>
        <div *ngFor="#thing of categories.things">
            <label *ngIf="isMultiSelectMode">
                <input type="checkbox" (change)="updateThingSelection(thing, $event)" />
                <img [src]="thing.image" /> {{ thing.name }}
            </label>
            <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode">
                <img [src]="thing.image" /> {{ thing.name }}
            </a>
        </div>
    </div>
</template>
<template [ngIf]="! isCategoryGrouped">
    <div *ngFor="#thing of things">
        <label *ngIf="isMultiSelectMode">
            <input type="checkbox" (change)="updateThingSelection(thing, $event)" />
            <img [src]="thing.image" /> {{ thing.name }}
        </label>
        <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode">
            <img [src]="thing.image" /> {{ thing.name }}
        </a>
    </div>
</template>

我真的很想重复部分内容,而不必编写完全独立的组件并将它们连接在一起,这需要一个TypeScript文件和一个模板。一种方法是使用本地组件,如下所示:

<sub-component selector="thing-list" things="input">
    <div *ngFor="#thing of things">
        <label *ngIf="isMultiSelectMode">
            <input type="checkbox" (change)="updateThingSelection(thing, $event)"/>
            <img [src]="thing.image" /> {{ thing.name }}
        </label>
        <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode">
            <img [src]="thing.image" /> {{ thing.name }}
        </a>
    </div>
</sub-component>

<template [ngIf]="isCategoryGrouped">
    <div *ngFor="#categories of categories">
        <div>{{ categories.category.name }}</div>
        <thing-list things="categories.things" />
    </div>
</template>
<thing-list [ngIf]="! isCategoryGrouped" things="things" />

我意识到上面是粗略的草图,可能不会按原样工作,但显然无法重复使用这样的部分视图是不幸的。如果我理解正确的话,React中的这种事情很简单。

我很好奇其他人已经解决了视图部分重复使用的优雅方式,而没有编写新的组件(我们的设计师需要了解这些组件和风格等等)。 ..)。感谢。

4 个答案:

答案 0 :(得分:4)

如果你的部分结构相同,只是数据不同,你可以想出一个更通用的模型。而不是直接引用categorything,而是将它们映射到您在服务到达视图之前填充的通用对象。

<div *ngFor="#item of items">
        ---
</div>

此处的项目将从事物或类别中填充。

然后您可以这样称呼它

<component [items]="fromThings"></component>
<component [items]="fromCategories"></component>

您基本上是通过不直接依赖实际对象来规范化视图。

答案 1 :(得分:3)

您还可以*ngFor使用[ngForTemplate]或即将发布的NgInsert(名称将被更改),以使模板的某些部分可以重复使用。

答案 2 :(得分:1)

您现在可以使用<ng-template>

<ng-template #headerPanel>
    <header>
       This is my reusable header.
    </header>
</ng-template>

然后像这样使用:

  <ng-container *ngTemplateOutlet="headerPanel"></ng-container>

Official docs

注意:我没有足够的知识来解释[ngTemplateOutlet]*ngTemplateOutlet之间的区别,但是如果其他人想要编辑此答案或添加另一个答案,请不要这样做。

答案 3 :(得分:0)

在模板中递归调用组件。

isList控制使用哪个部分,默认为false

<强> thing.html

<template [ngIf]="isLlist">
    <div *ngFor="#thing of things">
        <label *ngIf="isMultiSelectMode">
            <input type="checkbox" (change)="updateThingSelection(thing, $event)"/>
            <img [src]="thing.image" /> {{ thing.name }}
        </label>
        <a href="javascript: void(0)" (click)="selectThing(thing)" *ngIf="! isMultiSelectMode">
            <img [src]="thing.image" /> {{ thing.name }}
        </a>
    </div>
</template>

<template [ngIf]="!isList">

    <template [ngIf]="isCategoryGrouped">
        <div *ngFor="#categories of categories">
            <div>{{ categories.category.name }}</div>
            <my-thing-component [isList]="true" [things]="categories.things"></my-thing-component>
        </div>
    </template>

    <templete [ngIf]="! isCategoryGrouped">
        <my-thing-component [isList]="true" [things]="things"></my-thing-component>
    </templete>

</template>

<强> thing.component.ts

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

@Component({
    selector: 'my-thing-component',
    templateUrl: 'thing.html' 
})
export class ThingComponent {
    @Input() isList = false;
    @Input() things;

    //Fill in the rest
}