ç§ã®çµéšã§ã¯ãå žåçãªãšã³ã¿ãŒãã©ã€ãºã¢ããªã±ãŒã·ã§ã³ã¯ãäºãã«ãããã«ç°ãªãæ°çŸïŒå Žåã«ãã£ãŠã¯æ°åïŒã®ã»ãŒåäžã®ããŒãžã§ãã ç¹°ãè¿ãæ©èœãåå¥ã®ã³ã³ããŒãã³ãã«åé¢ãããã©ã¡ãŒã¿ãŒãšå®è£ ããããã³ãã¬ãŒãã䜿çšããŠç¹å®ã®åäœã決å®ããã®ããããšæãã®ã¯ãç§ãèããããšã ãã§ã¯ãªãã£ããšæããŸãã Angular 2ãæäŸãããã®ãèŠãŠã¿ãŸãããã
ã·ã³ãã«ãªãªãã·ã§ã³
æåã«æãæµ®ãã¶ã®ã¯ãç¹å¥ãªã¿ã°<ng-content select = "...">ã䜿çšããŠDOMã«ã³ã³ããŒãã³ã宣èšã®å 容ãåæ ããããšã§ãã
äŸãšããŠåçŽãªãŠã£ãžã§ããã³ã³ããŒãã³ãã䜿çšããŠããã®ã¢ãããŒããå®èšŒããããšããŸãã
æåã®äœ¿çšäŸïŒ
<widget> <div class="content"> <button> Just do my job... </button> </div> <div class="settings"> <select> <option selected="true">Faster</option> <option>Slower</option> </select> </div> </widget>
ãããŠããã¯ã©ã®ããã«èŠãããïŒ
ãŠã£ãžã§ããã³ã³ããŒãã³ãå ã§ã2ã€ã®èŠçŽ ãå®çŸ©ããŸãã
- ã¯ã©ã¹ãã³ã³ãã³ããã§ããŒã¯-ãŠã£ãžã§ããã®ã¡ã€ã³ã³ã³ãã³ãã
- ãèšå®ãã¯ã©ã¹ã«ãã£ãŠããŒã¯-ãŠã£ãžã§ããã«é¢é£ããããã€ãã®èšå®ã
ãŠã£ãžã§ããã³ã³ããŒãã³ãèªäœã以äžãæ åœããŸãã
- ãã¬ãŒã ãšã¿ã€ãã«ãæç»ããŸãã
- ã¡ã€ã³ã³ã³ãã³ã衚瀺ã¢ãŒããšèšå®è¡šç€ºã¢ãŒããåãæ¿ããããžãã¯ã
次ã«ããŠã£ãžã§ããã³ã³ããŒãã³ãèªäœãèŠãŠã¿ãŸãããã
@Component({ selector: "widget", template: ` <style> .. </style> <div class="hdr"> <span>Some widget</span> <button *ngIf="!settingMode" (click)="settingMode = true" class="wid_btn"> Settings </button> <button *ngIf="settingMode" (click)="settingMode = false" class="wid_btn"> Ok </button> </div> <div class="cnt"> <ng-content *ngIf="!settingMode" select=".content"> </ng-content> <div *ngIf="settingMode"> Settings: <ng-content select=".settings"> </ng-content> </div> <div> `}) export class Widget { protected settingMode: boolean = false; }
2ã€ã®ng-contentã¿ã°ã«æ³šç®ããŠãã ããã ãããã®åã¿ã°ã«ã¯selectå±æ§ãå«ãŸããŠãããããã䜿çšããŠãå ã®ng-contentã眮ãæããããšãç®çãšããèŠçŽ ãæ€çŽ¢ãããŸãã ãããã£ãŠãããšãã°ããŠã£ãžã§ããã衚瀺ããå ŽåïŒ
<ng-content select=".settings" />
ã¯
..
ã«çœ®ãæããã
..
<ng-content select=".content"/>
ã«ãã£ãŠ
..
åœç¶ãèŠçŽ ã®æ€çŽ¢ã¯<widget> ... </ widget>ã¿ã°ã«éå®ãããŸãã¯ã©ã€ã¢ã³ãã®ããŒã¯ã¢ããã 眮æãèŠã€ãããªãã£ãå Žåãäœã衚瀺ãããŸããã è€æ°ã®èŠçŽ ãéžææ¡ä»¶ãæºããå Žåãããããã¹ãŠã衚瀺ãããŸãã
ããé£ãããªãã·ã§ã³
äžèšã®ã¢ãããŒãã¯ããã³ãã¬ãŒãã³ã³ããŒãã³ããäœæããå¿ èŠãããå€ãã®å Žåã«æ£åžžã«é©çšã§ããŸããããã®ã¢ãããŒãã§ã¯äžååãªå ŽåããããŸãã ããšãã°ãã³ã³ããŒãã³ãã«æž¡ããããã³ãã¬ãŒããç°ãªãã³ã³ããã¹ãã§è€æ°å衚瀺ããå¿ èŠãããå Žåã åé¡ã説æããããã«ã次ã®ã¿ã¹ã¯ãèããŠã¿ãŸããããäŒæ¥ã¢ããªã±ãŒã·ã§ã³ã«ã¯ããªããžã§ã¯ãã®ãªã¹ããå«ãããã€ãã®ããŒãžããããŸãã åããŒãžã«ã¯ç¹å®ã®ã¿ã€ãã®ãªããžã§ã¯ãïŒãŠãŒã¶ãŒã泚æãªã©ïŒã衚瀺ãããŸãããåæã«åããŒãžã§ã¯ãªããžã§ã¯ãã®ããŒãžåå²ïŒããŒãžã³ã°ïŒãå¯èœã§ãããŸãããåé€ããªã©ã®ã°ã«ãŒãæäœãå®è¡ããããã«ãªããžã§ã¯ããããŒã¯ããæ©èœããããŸãã èŠçŽ ã®ããŒãžã³ã°ãšéžæãæ åœããã³ã³ããŒãã³ããå¿ èŠã§ããããŠãŒã¶ãŒãšæ³šæã¯éåžžã¯ç°ãªãæ¹æ³ã§è¡šç€ºããå¿ èŠããããããèŠçŽ ã®è¡šç€ºæ¹æ³ã¯ç¹å®ã®ããŒãžã®è²¬ä»»ã®ãŸãŸã§ããããã¯è«ççã§ãã åæ§ã®ã¿ã¹ã¯ã®å Žåã ng-content㯠1ã€ã®ãªããžã§ã¯ããå¥ã®ãªããžã§ã¯ãã®å åŽã«è¡šç€ºããã ããªã®ã§ããã¯ãé©åã§ã¯ãããŸãããã衚瀺ããã ãã§ãªããåãªããžã§ã¯ãã®å察åŽã®ããã¯ã¹ããã§ãã¯ããå¿ èŠããããŸãïŒåã ã®ã³ã³ããã¹ãïŒã
ä»åŸããŠãŒã¶ãŒã«é¢ããæ å ±ã衚瀺ããããã«æ§æããããªã¹ãããã²ãŒã¿ãŒãã³ã³ããŒãã³ãã®äŸã䜿çšããŠããã®åé¡ã®è§£æ±ºçãããã«ç€ºããŸãïŒ ãœãŒã¹ã³ãŒãã¯ãã¡ã ïŒã
<list-navigator [dataSource]="dataSource" [(selectedItems)]="selectedUsers"> <div *list-navigator-item="let i, let isSelected = selected" class="item-container" [class.item-container-selected]="isSelected" > <div class="item-header">{{i.firstName}} {{i.lastName}}</div> <div class="item-details"> Id: {{i.id}}, Email: {{i.email}}, Gender: <span [ngClass]="'item-details-gender-'+ i.gender.toLowerCase()"> {{i.gender}} </span> </div> </div> </list-navigator>
èãæ¹ã¯æ¬¡ã®ãšããã§ãããã©ã¡ãŒã¿ãŒãšããŠã®ã³ã³ããŒãã³ãã¯ããªãã»ãããšããŒãžãµã€ãºïŒoffsetãšpageSizeïŒã§ãªããžã§ã¯ãã®ç¯å²ãè¿ãé¢æ°ãžã®ãªã³ã¯ãåãåããŸãã
[dataSource]="dataSource"
this.dataSource = (o, p) => this._data.slice(o, o + p);
ãããã®ãªããžã§ã¯ãã衚瀺ããæ¹æ³ã説æãããã³ãã¬ãŒããšåæ§ã«ïŒ
<div *list-navigator-item="let i, let isSelected = selected"âŠ
åŒæ°* list-navigator-itemã¯ãããŒã¯ãããèŠçŽ ããã³ãã¬ãŒãã§ããããšãã³ã³ããŒãã³ããç解ã§ããããã«ããããŒã«ãŒã®äžçš®ã§ãïŒã*ãèšå·ã¯ãåã«èŠçŽ ã§ã¯ãªããã³ãã¬ãŒãã§ããããšãè§åºŠã«ç€ºããŸãïŒ dataSourceã«ãã£ãŠè¿ãããç¯å²ãã次ã®ãªããžã§ã¯ããæç»ããŸãã list-navigator-itemã䜿çšããŠã 2ã€ã®å€æ°ãèšå®ããŸãã
- let i-ç¯å²ãã次ã®ãªããžã§ã¯ãã«ãªã³ã¯ããŸãã
- let isSelected = selected-ãã®èŠçŽ ããã§ãã¯ãããŠãããã©ããã瀺ãããŒã«å€
ãã©ããïŒåŸã§ã=éžæãã«ã€ããŠèª¬æããŸãïŒã
ããã«ãã³ã³ããŒãã³ãã¯ãã©ã¡ãŒã¿ãšããŠãéžæãèŠçŽ ã®ãªã¹ãïŒãã§ãã¯ããŒã¯ãä»ããŸãïŒãåãåãããŠãŒã¶ãŒãéžæãå€æŽãããšãã³ã³ããŒãã³ãã¯ãŠãŒã¶ãŒã®éžæã«å¯Ÿå¿ããæ¢ã«æŽæ°ããããªã¹ããè¿ããŸãã
[(selectedItems)]="selectedUsers"
次ã®é¡äŒŒç¹ãæãããšãã§ããŸãããfactoryãã³ã³ããŒãã³ããã³ã³ããŒãã³ãã«æž¡ããã³ã³ããŒãã³ãããæž¡ããããã©ã¡ãŒã¿ãŒã䜿çšããŠæ°ããã€ã³ã¿ãŒãã§ã€ã¹èŠçŽ ãäœæããŸãã 次ã«ãã³ã³ããŒãã³ãã¯ããã¡ã¯ããªãŒã«ãã£ãŠäœæãããã€ã³ã¿ãŒãã§ãŒã¹èŠçŽ ãå éšã§å¿ èŠãªå Žæã«é 眮ããŸãïŒãã®äŸã§ã¯ãã§ãã¯ããŒã¯ã®å察åŽïŒã
æåŸã«ããã®ãããªã³ã³ããŒãã³ãã調çããæ¹æ³ãèŠãŠã¿ãŸãããã ãããè¡ãã«ã¯ã次ã®æåãå¿ èŠã§ãã
- list-navigator-item-outlet-ã¢ãŠãã¬ãããã£ã¬ã¯ãã£ããå®éã«ã¯ããã³ãã¬ãŒããšçŸåšã®ã³ã³ããã¹ãã䜿çšããŠæ°ããèŠçŽ ãäœæããŸãïŒäžèšã®ã¢ãããžãŒã®ããã¡ã¯ããªãŒãïŒïŒã³ã³ããŒãã³ãã®å éšå®è£ ã®äžéšïŒã
- list-navigator-item-context âã³ã³ããã¹ãããŒã¿ïŒã³ã³ããŒãã³ãã®å éšå®è£ ã®äžéšïŒã転éããããã®ã³ã³ããã¯ã©ã¹ã
- list-navigator-item-ã³ã³ããŒãã³ãããã³ãã¬ãŒãèŠçŽ ã«ã¢ã¯ã»ã¹ããããã®ããŒã«ãŒãã£ã¬ã¯ãã£ãã
- list-navigator-å®éã«ã¯ãäž»èŠãªåäœãã€ãŸãããŒãžã³ã°ãšèŠçŽ ã®éžæãå®è£ ããã³ã³ããŒãã³ãã§ãã
ãªã¹ãããã²ãŒã¿ãŒã¢ã€ãã ã¢ãŠãã¬ãã
ã泚æ å®éããã®ãã£ã¬ã¯ãã£ãã¯æšæºã©ã€ãã©ãªã«å«ãŸããŠããNgTemplateOutletãã£ã¬ã¯ãã£ããè€è£œããããå¿ èŠãããŸããããäœãèµ·ããŠãããããããã説æããããã«ç¬èªã®ããŒãžã§ã³ã䜿çšããããšã«ããŸããã
éåžžã«å°ããªãã£ã¬ã¯ãã£ããªã®ã§ããœãŒã¹ã³ãŒãå šäœãæäŸããŸãã
@Directive({ selector: "list-navigator-item-outlet" }) export class ListNavigatorItemOutlet { constructor(private readonly _viewContainer: ViewContainerRef){} @Input() public template: TemplateRef<ListNavigatorItemContext>; @Input() public context: ListNavigatorItemContext; public ngOnChanges(changes: SimpleChanges): void { const [, tmpl] = analyzeChanges(changes, () => this.template); const [, ctx] = analyzeChanges(changes, () => this.context); if (tmpl && ctx) { this._viewContainer.createEmbeddedView(tmpl, ctx); } } }
ã³ã³ã¹ãã©ã¯ã¿ãŒã§ã ViewContainerRefåã®ãªããžã§ã¯ãã®Angular 2ãã¯ãšãªããŸãã ãã®ãªããžã§ã¯ãã䜿çšããŠã芪ã³ã³ããŒãã³ãã®èŠèŠèŠçŽ ïŒViewïŒïŒãã©ãŠã¶ã®DOMèŠçŽ ãšæ··åããªãã§ãã ããïŒãå¶åŸ¡ã§ããŸãã ViewContainerRefã®ãã¹ãŠã®æ©èœã®äžã§ãæ°ããèŠèŠèŠçŽ ãäœæããå¯èœæ§ã«çŸåšé¢å¿ããããŸããããã¯ã次ã®2ã€ã®æ¹æ³ã䜿çšããŠå®è¡ã§ããŸãã
- createComponentïŒcomponentFactoryïŒComponentFactory <C>ã...ïŒ
- createEmbeddedViewïŒtemplateRefïŒTemplateRef <C>ãã³ã³ããã¹ãïŒïŒCã...ïŒ
æåã®æ¹æ³ã¯ããã¯ã©ã¹ãã®ã¿ãæã«ã³ã³ããŒãã³ããåçã«äœæããå Žåã«åœ¹ç«ã¡ãŸãã ãã®æ¹æ³ã¯ãããšãã°ãAngular Routerã«ãã£ãŠäœ¿çšãããŸããããã®ãããã¯ã¯å¥ã®æçš¿ã«å€ããŸãïŒãã¡ããèå³æ·±ãå ŽåïŒã 次ã«ããŠãŒã¶ãŒãäœæãã2ã€ç®ã®ã¡ãœããcreateEmbeddedViewã«æ³šç®ããŸãããã ãã©ã¡ãŒã¿ãŒãšããŠã TemplateRefãšç¹å®ã®ã³ã³ããã¹ããåããŸãã
TemplateRefã¯ãæ°ããããžã¥ã¢ã«ã³ã³ããŒãã³ããäœæããããã®ããã¡ã¯ããªãã§ãããã³ã³ããŒãã³ãã¬ã€ã¢ãŠãïŒãã³ãã¬ãŒãïŒ '...'ãŸãã¯templateUrlïŒ "..."ã®<template>ã¿ã°ããã³ã³ãã€ã«ãããããšã«ãã£ãŠååŸãããŸãïŒã ããããä»ãŸã§ããã®ã¿ã°ã¯ã©ãã«ãèŠãããŸããã§ãããTemplateRefã¯ã©ãããæ¥ãã®ã§ããããïŒ å®éã <template>ã¿ã°ããããã*ãèšå·ã®åœ¢åŒã§æ§æç³ã䜿çšããŠæé»çã«å®çŸ©ããŸããã
<div *list-navigator-item="let i, let isSelected = selected"âŠ
åçã«
<template [list-navigator-item]="let i, let isSelected = selected" <div âŠ
Angular 2ã¯ãã³ã³ããŒãã³ãã¬ã€ã¢ãŠãã§èŠã€ãã£ã<template>ã® TemplateRefãäœæããŸãã
createEmbeddedViewã«æ»ããŸãã ãã®ã¡ãœããã®2çªç®ã®åŒæ°ã¯ã³ã³ããã¹ãã§ãã ãã®ãªããžã§ã¯ãã¯ããã³ãã¬ãŒãã§å®çŸ©ãããå€æ°ã®å€ãåæåã§ãããããéåžžã«éèŠã§ãã
"let i, let isSelected = selected"
ããã§ããå°ãæ§æçãªç ç³ããããŸããAngular2ã®ãã®ãšã³ããªã¯æ¬¡ã®ããã«ç解ããŸãã
"let i=$implicit, let isSelected = selected"
ã€ãŸãããã®å Žåã ã³ã³ããã¹ããªããžã§ã¯ãã«ã¯ã $ implicitãšselectedã® 2ã€ã®ããããã£ãå¿ èŠã§ãã ã ããïŒ
export class ListNavigatorItemContext { constructor( public $implicit: any, public selected: boolean ) { } }
ããã§ã list-navigator-item-outletã®ä»çµã¿ãç解ããããã®ãã¹ãŠã®ç¥èãåŸãããŸããã ãã³ãã¬ãŒãããããã£ãšã³ã³ããã¹ãããããã£ã®äž¡æ¹ãèšå®ããããšããã«ããã£ã¬ã¯ãã£ãã¯ã³ã³ããå ã«æ°ããèŠèŠèŠçŽ ãäœæããŸãã
ããã§ã次ã®äºçŽãè¡ãå¿ èŠããããŸããè¯ãæ¹æ³ã§ã¯ã ngOnChangesãå床åŒã³åºããšãã«ä»¥åã«äœæããããžã¥ã¢ã«ã³ã³ããŒãã³ããåé€ããå¿ èŠããããŸãããããã¯ãã¬ãŒãã³ã°ã®äŸã§ã¯å¿ èŠãããŸããã
ãªã¹ãããã²ãŒã¿ãŒã¢ã€ãã
ããã§ã¯ãã¹ãŠãéåžžã«ç°¡åã§ãã
@Directive({ selector: "[list-navigator-item]" }) export class ListNavigatorItem { constructor(@Optional() public readonly templateRef: TemplateRef<ListNavigatorItemContext>) { } }
ãã®ãã£ã¬ã¯ãã£ãã®å¯äžã®ç®çã¯ãã³ã³ãã€ã«ããããã³ãã¬ãŒãããããªãã¯ããããã£ã«æž¡ãããšã§ãã
ãªã¹ãããã²ãŒã¿ãŒ
æåŸã«ããã¹ãŠãéå§ãããã¡ã€ã³ã³ã³ããŒãã³ãã ã¬ã€ã¢ãŠãããå§ããŸãããïŒ
<div *ngFor="let i of itemsToDisplay"> <div> <input type="checkbox" [ngModel]="i.selected" (ngModelChange)="onSelectedChange(i, $event)"/> </div> <div class="item-wrapper"> <list-navigator-item-outlet [template]="templateOutlet.templateRef" [context]="i"> </list-navigator-item-outlet> </div> </div> <div> <button (click)="onPrev()">Prev</button> <button (click)="onNext()">Next</button> </div>
ããã§ïŒ
this.itemsToDisplay = this .dataSource(offset, pageSize) .map(i => new ListNavigatorItemContext( i, this.selectedItems.indexOf(i) >= 0)); ⊠@ContentChild(ListNavigatorItem) protected templateOutlet: ListNavigatorItem;
åäœåçïŒ
- 察å¿ããé¢æ°ïŒ dataSource ïŒãžã®ãªã³ã¯ã䜿çšããŠãªããžã§ã¯ãã®æ¬¡ã®ããããååŸãããããitemsToDisplayã«å ¥ããŸã
- éšåãããã¹ãŠã®ãªããžã§ã¯ãããœãŒããïŒ * ngFor = "let i of itemsToDisplay" ïŒãåãªããžã§ã¯ãã«å¯ŸããŠããã§ãã¯ããŒã¯ãšãäžèšã®list-navigator-item-outletãäœæãããã©ã¡ãŒã¿ãŒãšããŠåãåããŸãã
- éžæããããªããžã§ã¯ããšãã©ã°å±æ§ã§æ§æãããã³ã³ããã¹ãã
- TemplateRefãžã®ãªã³ã¯ãããã¯ã list-navigator-itemãã£ã¬ã¯ãã£ãã«ãã£ãŠèŠªåã«æäŸããããªã¯ãšã¹ã@ContentChildïŒListNavigatorItemïŒã宣èšããããšã§èŠã€ãããŸããã
- list-navigator-item-outletã¯ãæž¡ããããã³ãã¬ãŒããšã³ã³ããã¹ãã䜿çšããŠæ¬¡ã®ãªããžã§ã¯ãã®èŠèŠèŠçŽ ãäœæããŸãïŒå®éã®ãããžã§ã¯ãã§NgTemplateOutletã䜿çšããããšããå§ãããŸãïŒã
å°ããªè¿œå ã
ãªã¹ãããã²ãŒã¿ãŒã®ãã³ãã¬ãŒãã¯éåžžã«ã€ã³ã¿ã©ã¯ãã£ãã§ãããã¿ã³ããã§ãã¯ããã¯ã¹ãå
¥åãã£ãŒã«ããè¿œå ãããã¹ãŠã芪ããŒãžãã管çã§ããŸãã 以äžã¯ã ãã¢ãŒã«ã€ãããã¿ã³ãè¿œå ãããäŸã§ãããã®ãã¿ã³ã®ãã³ãã©ãŒã¯èŠªããŒãžã«ããããŠãŒã¶ãŒã®ç¶æ
ãå€æŽããŸãã
<list-navigator..> <div *list-navigator-item="let i..." > ... <button *ngIf="!i.archived" class="btn-arch" (click)="onArchive(i)">Archive</button> ... </div> </list-navigator>
protected onArchive(user: User){ user.archived = true; }
å®éãããããã¹ãŠã§ãã ãã®èšäºã§ã¯ãAngular 2ã®æšæºããã¥ã¡ã³ãããããã«è¶ ããããªãã¯ã«ã€ããŠèª¬æããŠããããã誰ãã«åœ¹ç«ã€ãšæããŸãã ç¹°ãè¿ãã«ãªããŸããããã®èšäºã«èšèŒãããŠããäŸã®ãœãŒã¹ã³ãŒããžã®ãªã³ã¯ã瀺ããŸãã ïŒ ãã¢ãŒã«ã€ãããã¿ã³ã®ãªãã·ã§ã³ ïŒã