Angular 5:如何使用ES6 / ES5注入路由器服务(不带打字稿)



TL;博士

我想将 Angular 路由器服务注入到 ES6/ES5 的组件中(是的,没有 Typescript :p(。


大家好,

我最近为 javascript 创建了一个 Angular 5 代理,因为我不想使用 Typescript。

我的库在github上可用:https://github.com/kevinbalicot/angular-js-proxy。

当您想要创建组件,可注入服务和NgModule时,它就可以工作。

在jsFiddle上查看此示例 https://jsfiddle.net/kevinbalicot/nynzceb1/

// ng variable contains { compiler, common, core, router, platformBrowserDynamic, platformBrowser } from Angular 5 library
class Service {
constructor() {}
toUpperCase(string) {
return String(string).toUpperCase();
}
}
// Like @Injectable
Injectable({})(Service);
class HomeComponent {
constructor(service) {
this.message = service.toUpperCase('hello');
}
}
// Like @Component
Component({
selector: 'home-component',
providers: [Service],
template: `
<h1>{{ message }}</h1>
`
})(HomeComponent);
class Module {
constructor() {}
}
// Like @NgModule
NgModule({
imports: [ng.platformBrowser.BrowserModule],
declarations: [HomeComponent],
providers: [],
bootstrap: [HomeComponent]
})(Module);
ng.platformBrowserDynamic.platformBrowserDynamic().bootstrapModule(Module);

您将能够创建可注入服务并将其注入到组件中。

问题所在

例如,当我想注入像路由器这样的 Angular 服务时,我收到 Angular 注入器错误

Error: Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?, ?).

jsFiddle 上的演示 https://jsfiddle.net/kevinbalicot/nynzceb1/4/

// ng variable contains { compiler, common, core, router, platformBrowserDynamic, platformBrowser } from Angular 5 library
class Service {
constructor() {}
toUpperCase(string) {
return String(string).toUpperCase();
}
}
// Like @Injectable
Injectable({})(Service);
class HomeComponent {
constructor(service, router) {
this.message = service.toUpperCase('hello');
}
}
// Like @Component
Component({
selector: 'home-component',
providers: [Service, ng.router.Router],
template: `
<h1>{{ message }}</h1>
`
})(HomeComponent);
class Module {
constructor() {}
}
// Like @NgModule
NgModule({
imports: [
ng.platformBrowser.BrowserModule,
ng.router.RouterModule
],
declarations: [HomeComponent],
providers: [],
bootstrap: [HomeComponent]
})(Module);
ng.platformBrowserDynamic.platformBrowserDynamic().bootstrapModule(Module);

我是否必须以不同于自定义可注入服务的方式注入 Angular 服务?(我的代码在这里:https://github.com/kevinbalicot/angular-js-proxy/blob/master/src/index.js#L51(。

function NgModule(metadata = {}) {
return function decorator(target) {
target.annotations = [new core.NgModule(metadata)];
target.parameters = [];
if (!!metadata.providers && Array.isArray(metadata.providers)) {
metadata.providers.forEach(provider => {
if (!provider.useValue && !provider.useClass) {
// Like Service class on example
target.parameters.push([new core.Inject(provider)]);
} else {
// Like { provide: LOCALE_ID, useValue: 'en-EN' } provider
target.parameters.push([new core.Inject(provider.provide), provider.useValue || provider.useClass]);
}
});
}
return target;
}
}

感谢您的阅读,欢迎任何想法。


编辑我的问题,这与 ES2 和 ES5 中的 Angular 6 依赖注入不同

因为,版本 4 和 5 之间的依赖注入并不相同 (https://github.com/angular/angular/blob/master/CHANGELOG.md#breaking-changes(

Injectable仅适用于TypeScript,它使用发出的参数类型来注释DI的可注入类。

类应该在 ES5 和 ES6 中使用静态parameter属性进行注释,如以下答案所示:

class HomeComponent {
constructor(service, router) {
this.message = service.toUpperCase('hello');
}
}
HomeComponent.parameters = [
[new ng.core.Inject(Service)],
[new ng.core.Inject(ng.router.Route)]
];

此示例的一个问题是Router应该是全局提供程序,而不应在组件providers中定义。下面是一个示例。

对于像 Router 这样的 Angular 服务,它不应该在组件提供程序中定义,因为 Route 应该是全局提供程序。

这里的例子 https://jsfiddle.net/kevinbalicot/nynzceb1/6/

// ng variable contains { compiler, common, core, router, platformBrowserDynamic, platformBrowser } from Angular 5 library
class DefaultComponent {
constructor(route) {
this.route = route;
}
}
// You can override class parameters for inject Angular service
DefaultComponent.parameters = [[new ng.core.Inject(ng.router.ActivatedRoute)]];
// Like @Component
Component({
template: `
<h2>Route : {{ route }}</h2>
`
})(DefaultComponent);

谢谢@estus

最新更新