2016-04-14 2 views
5

Я пишу некоторые шаблоны Angular2, которые имеют повторяющиеся части с различными контейнерами. В этом случае представление может измениться, если все сгруппировано, и если включен режим нескольких секций. Пожалуйста, извините за длинный пример, но что-то вроде этого: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> 

Я бы очень хотел, чтобы повторно использовать части этого без необходимости писать совершенно отдельный компонент и провод все вместе, для чего потребуется файл машинопись и шаблон. Один из способов будет с локальными компонентами, что-то вроде этого:

<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" /> 

Я понимаю, что выше грубый эскиз и, вероятно, не будет работать, как есть, но очевидная неспособность повторно использовать части представления, как это прискорбно , Если я правильно понимаю, это довольно просто в Реактике.

Мне любопытно, как другие люди решили повторное использование частей, не задумываясь о том, чтобы написать новый компонент (который наши дизайнеры тогда должны были знать и стиль и т. Д. .). Благодарю.

+0

Мне непонятно, какие части зрения вы хотите повторно использовать, каким образом. –

ответ

4

Если ваши разделы идентичны по своей структуре, просто разные по данным, вы можете придумать более общую модель. Вместо того, чтобы напрямую ссылаться на category и thing, сопоставьте их с общим объектом, который вы заполняете в службе, прежде чем он попадет в представление.

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

Здесь предметы будут либо заполнены от вещей, либо категорий.

Вы можете назвать это как так

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

Вы в основном нормализации зрения, не в зависимости от реальных объектов непосредственно.

+2

Проблема заключается в том, когда дети должны дублироваться с разными родителями, поэтому я не могу использовать цикл. Вторая часть этого ответа - именно то, чего я хочу избежать - создание нового компонента. Причина, по которой я не хочу создавать новый компонент, состоит в том, что дублированные части дерева очень специфичны для этого представления. Я в основном хочу что-то аналоговое для внутренних или классов методов в юниверсе java/scala. –

+0

Итак, с этим предложением вы сохраняете его как один компонент, но передаете ему объект, населенный двумя разными вариантами. Вы нормализуете его в основном на третий объект модели. – TGH

+2

Правильно ... но у вас все еще есть отдельный компонент из контекста, где он используется, что конкретно я пытаюсь избежать. См. Ответ Günter, который указывает на запрос на тягу для функции, о которой я прошу. –

3

Вы также можете использовать *ngFor с [ngForTemplate] или предстоящий NgInsert (имя будет изменено), чтобы сделать части вашего шаблона многоразовыми.

+0

'ngInsert' кажется новым термином для меня, что использовать то же самое, хорошо, если вы обновите свой ответ с более подробным объяснением. –

+1

Перейдите по ссылке. Он будет называться по-разному. Он просто позволяет вам штамповать ссылочные шаблоны. Надеюсь сначала получить больше информации о требованиях, а затем уточню свой ответ. –

+0

Это выглядит потрясающе, и это почти то, что я хочу. Не могу дождаться, пока он упадет в бета-версию. Любая приблизительная оценка того, когда это произойдет? –

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.ц

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 
} 
0

Теперь вы можете использовать <ng-template>

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

Затем используйте так:

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

Official docs

Примечание: Я не достаточно хорошо осведомлены, чтобы объяснить differe nce между [ngTemplateOutlet] и *ngTemplateOutlet, но если кто-то хочет отредактировать этот ответ или добавить другого, не стесняйтесь.

Смежные вопросы