仕事の制約のためにES6 / ES7を使い続けながら、ロープを学び、切り替えを試みているため、Angular 2内でカスタムコンポーネントに取り組んでいます。次のように定義されたコンポーネントがあるとします。
// Import Inject, Component and View constructor (for metadata)
import {Inject, Injectable} from 'angular2/core';
import {Component, View} from 'angular2/core';
// Import NgClass directive
import {NgClass} from 'angular2/common';
import { InjectMetadata } from 'angular2/core';
// # Accordion Component
@Component({
selector: 'accordion, [accordion]',
// Modify the `host` element with a css class designator
host: {
'class': 'panel-group'
}
})
// Define the view of our `Component` using one or more
// `View` annotations
@View({
// Link to our external template file
templateUrl: './components/accordion/accordion.html'
})
// Create and export `Component` class
export class Accordion {
constructor() {
this.groups = [];
}
// Function to register groups
addGroup(group) {
this.groups.push(group);
}
closeOthers(openGroup) {
this.groups.forEach((group) => {
if(group !== openGroup) {
group.isOpen = false;
}
});
}
removeGroup(group) {
let index = this.groups.indexOf(group);
if(index !== -1) {
this.groups.splice(index, 1);
}
}
}
これを呼び出された別のコンポーネントに渡す必要がありますが、このスタック オーバーフロー スレッドAccordionGroup
の回答に従って、コンストラクターで行うように注入しようとすると、次のようになります。
// # AccordionGroup Component
// Annotate AccordionGroup class with `Component`
@Component({
selector: 'accordion-group, [accordion-group]',
inputs: ['heading', 'isOpen'],
// Let Angular know about `Accordion`
providers: [Accordion]
})
// Define the view of our `Component` using one or more
// `View` annotations
@View({
// Link to our external template file
templateUrl: './components/accordion/accordion-group.html',
// Specify which directives our `Component` will utilize with
// the `directive` property of the `View` annotation
directives: [NgClass]
})
// Create and export `Component` class
export class AccordionGroup {
constructor(accordion) {
this.isOpen = false;
this.accordion = accordion;
this.accordion.addGroup(this);
}
// Angular 2 DI desugar'd
// Reference: https://stackoverflow.com/questions/33026015/how-to-inject-angular2-http-service-into-es6-7-class
static get parameters() {
return [[Accordion]];
}
toggleOpen(event) {
event.preventDefault();
this.isOpen = !this.isOpen;
this.accordion.closeOthers(this);
}
onDestroy() {
this.accordion.removeGroup(this);
}
}
使用して
static get parameters() {
return [[Accordion]];
}
最初のコメントに記載されている修正を行った後、コンポーネントをレンダリングします。
次のいずれかを使用すると、コンポーネントがレンダリングされます。
AccordionGroup.parameters = [[Accordion]];
また
AccordionGroup.parameters = [new Inject(Accordion)];
あるいは
// Use reflect metadata as an attempt to inject appropriate
// dependency
@Reflect.metadata('parameters', [[new InjectMetadata(Accordion)]])
しかし、ES7 でパラメーター デコレーターを使用できるようになるまで、これらのうちどれを使用するのが適切な方法なのかという疑問が残ります。
余談ですが、コードの多くは、TypeScript を使用した Angular 2 のすべてを示すこの特定のチュートリアルからのものでした。Angular 2 へのディレクティブの移行