【问题标题】:Angular2 local components / template reuseAngular2本地组件/模板复用
【发布时间】:2016-08-05 08:44:13
【问题描述】:

我正在编写一些具有不同容器重复部分的 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 中非常简单。

我很好奇其他人解决视图重用问题的优雅方式,而无需编写新组件(然后我们的设计师需要了解和样式等... )。谢谢。

【问题讨论】:

  • 我不清楚您希望以哪种方式重用视图的哪些部分。

标签: angular angular2-template


【解决方案1】:

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

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

这里的项目可以从事物或类别中填充。

你可以这样称呼它

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

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

【讨论】:

  • 当前的问题是孩子需要与不同的父母复制,所以我不能使用循环。这个答案的第二部分正是我想要避免的——制作一个新组件。我不想制作新组件的原因是树的重复部分非常特定于该视图。我基本上想要一些类似于 java/scala 宇宙中的内部或方法类的东西。
  • 因此,根据这个建议,您可以将其保留为一个组件,但传递一个由两个不同变体填充的对象。您基本上将其标准化为第三个模型对象。
  • 对...但是您仍然有一个与使用它的上下文不同的组件,这正是我要避免的。请参阅 Günter 的答案,它指向我要求的功能的拉取请求。
【解决方案2】:

您还可以将*ngFor[ngForTemplate] 或即将推出的NgInsert(名称将更改)一起使用,以使您的部分模板可重复使用。

【讨论】:

  • ngInsert 对我来说似乎是一个新术语,相同的用途有什么用,如果您更新答案并提供更多解释,那就太好了。
  • 查看链接。它将以不同的方式命名。它只允许您标记引用的模板。我希望首先获得有关要求的更多信息,然后我会完善我的答案。
  • 这看起来很棒,几乎正是我想要的。等不及它进入测试版了。粗略估计什么时候会发生?
  • 很公平。也许我会编写我自己的该组件版本以供在此期间使用。谢谢。
【解决方案3】:

您现在可以使用&lt;ng-template&gt;

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

然后像这样使用:

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

Official docs

注意:我的知识不足以解释 [ngTemplateOutlet]*ngTemplateOutlet 之间的区别,但如果其他人想编辑此答案或添加另一个答案,请随意。

【讨论】:

    【解决方案4】:

    在模板中递归调用组件。

    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
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多