Angular 5: Как внедрить сервис Маршрутизатор с ES6 / ES5 (без Typescript) - PullRequest
0 голосов
/ 16 мая 2018

TL; DR

Я хочу внедрить службу Angular Router в компонент с ES6 / ES5 (да, без Typescript: p).


Привет всем,

Я недавно создал прокси Angular 5 для javascript, потому что я не хочу использовать Typescript.

Моя библиотека доступна на github: https://github.com/kevinbalicot/angular-js-proxy.

Это работает, когда вы хотите создать свой Компонент, ваш сервис Injectable и ваш 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);

Вы сможете создатьваш сервис Injectable и введите его в ваш компонент.

ПРОБЛЕМА

Когда я хочу ввести сервис Angular, например, Router, я получаю ошибку Angular Injector

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 иначе, чем настраиваемую службу Injectable?(Мой код здесь: 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;
    }
}

Спасибо за чтение, любая идея приветствуется.


РЕДАКТИРОВАТЬ Мой вопрос не совпадает с Внедрение зависимостей Angular 2 в ES5 и ES6

Поскольку внедрение версий не одинаково между версиями 4 и 5 (https://github.com/angular/angular/blob/master/CHANGELOG.md#breaking-changes)

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Для службы Angular, такой как Router, ее не следует определять в поставщиках компонентов, поскольку 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

0 голосов
/ 16 мая 2018

Injectable только для TypeScript, он использует испускаемые типы параметров для аннотирования вводимого класса для DI.

Классы должны быть аннотированы со статическим свойством parameter в ES5 и ES6, как показано в этот ответ :

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.Вот пример .

...