简体   繁体   English

Angular 5:如何在ES6 / ES5中注入路由器服务(无打字稿)

[英]Angular 5 : How to inject Router service with ES6/ES5 (without Typescript)

TL;DR TL; DR

I want to inject the Angular Router service into a component with ES6/ES5 (yes without Typescript :p). 我想将Angular Router服务注入具有ES6 / ES5的组件中(是,没有Typescript:p)。


Hello every body, 大家好,

I recently created an Angular 5 proxy for javascript, because I don't want to use Typescript. 我最近为javascript创建了Angular 5代理,因为我不想使用Typescript。

My library is available on github : https://github.com/kevinbalicot/angular-js-proxy . 我的库可在github上找到: https//github.com/kevinbalicot/angular-js-proxy

It's works when you want to create your Component, your Injectable service and your NgModule. 当您要创建组件,Injectable服务和NgModule时,它就可以使用。

Check out this example on jsFiddle https://jsfiddle.net/kevinbalicot/nynzceb1/ 在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);

You'll be able to create your Injectable Service and Inject it to your Component. 您将能够创建自己的可注入服务并将其注入到组件中。

THE PROBLEM 问题

When I want to inject an Angular service like Router for example, I get an Angular Injector error 例如,当我想注入诸如路由器之类的Angular服务时,出现Angular Injector错误

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

Demo on jsFiddle https://jsfiddle.net/kevinbalicot/nynzceb1/4/ 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);

Do I have to inject an Angular service differently than a custom Injectable Service ? 我是否必须以不同于自定义可注入服务的方式注入Angular服务? (My code here : https://github.com/kevinbalicot/angular-js-proxy/blob/master/src/index.js#L51 ). (我的代码在这里: 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;
    }
}

Thanks for reading, any idea is welcome. 感谢您的阅读,欢迎提出任何想法。


EDIT My question it's not the same of Angular 2 dependency injection in ES5 and ES6 编辑我的问题与ES5和ES6中Angular 2依赖注入不同

Because, dependency injections are not the same between versions 4 and 5 ( https://github.com/angular/angular/blob/master/CHANGELOG.md#breaking-changes ) 因为版本4和版本5之间的依赖项注入不同( https://github.com/angular/angular/blob/master/CHANGELOG.md#breaking-changes

Injectable is for TypeScript only, it uses emitted parameter types to annotate injectable class for DI. Injectable仅用于TypeScript,它使用发出的参数类型为DI注释可注入类。

Classes should be annotated with static parameter property in ES5 and ES6, as shown in this answer : 在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)]
];

A problem with this example is that Router should be global provider, it shouldn't be defined in component providers . 此示例的问题在于, Router应该是全局提供程序,而不应该在组件providers定义。 Here's an example . 这是一个例子

For Angular service like Router, it shouldn't be defined in component providers, because Route should be global provider. 对于路由器之类的Angular服务,不应在组件提供程序中定义它,因为Route应该是全局提供程序。

Example here https://jsfiddle.net/kevinbalicot/nynzceb1/6/ 此处的示例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);

Thanks @estus 谢谢@estus

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM