问题
I have been working on a custom component within Angular 2 as I attempt to learn the ropes and make the switch while staying with ES6/ES7 due to job constraints. Say I have a component defined such as this:
// 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);
}
}
}
I need to pass this into another component called AccordionGroup
but when I follow the answers in this Stack Overflow Thread and try to inject like I do with the constructor:
// # 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);
}
}
using
static get parameters() {
return [[Accordion]];
}
renders my component after making the correction noted in the first comment.
Using any of the following renders the component:
AccordionGroup.parameters = [[Accordion]];
or
AccordionGroup.parameters = [new Inject(Accordion)];
or even
// Use reflect metadata as an attempt to inject appropriate
// dependency
@Reflect.metadata('parameters', [[new InjectMetadata(Accordion)]])
but the question remain, which of these is the appropriate method to use until such a time when we can use parameter decorators with ES7.
As an aside, a lot of the code came from this particular tutorial which demonstrates all of the Angular 2 stuff with TypeScript, so I simply adapted it to my es6/es7 environment with Webpack | Migrating Directives to Angular 2
回答1:
You need to add the @Inject()
decorator on your constructor parameter.
As this is not supported by the ES7 spec (only class, property and methods decorators are allowed in the current spec AFAIK), you need to have some kind of plugin for your transpiler.
If you are using Babel to transpile, you can use the babel-plugin-angular2-annotations plugin to allow this and correctly transpile the code.
import {Inject} from 'angular2/core';
export class AccordionGroup {
constructor(@Inject(Accordion) accordion) {
// ...
}
}
回答2:
In addition to what Eric said in comment, perhaps you missed the @Inject
decorator within the AccordionGroup
constructor
import {Inject} from 'angular2/core';
export class AccordionGroup {
constructor(@Inject(Accordion) accordion) {
(...)
}
}
Hope it helps you, Thierry
来源:https://stackoverflow.com/questions/35089037/angular-2-how-should-we-be-handling-dependency-injection-with-es6-es7