Ошибка углового цифрового входа - ИСКЛЮЧЕНИЕ: не удается разрешить все параметры

Я создал базовое приложение на Angular, но столкнулся со странной проблемой, когда я не могу внедрить службу в один из моих компонентов. Тем не менее, он отлично вписывается в любой из трех других компонентов, которые я создал.

Для начала, это сервис:

import { Injectable } from '@angular/core';

@Injectable()
export class MobileService {
  screenWidth: number;
  screenHeight: number;

  constructor() {
    this.screenWidth = window.outerWidth;
    this.screenHeight = window.outerHeight;

    window.addEventListener("resize", this.onWindowResize.bind(this) )
  }

  onWindowResize(ev: Event) {
    var win = (ev.currentTarget as Window);
    this.screenWidth = win.outerWidth;
    this.screenHeight = win.outerHeight;
  }

}

И компонент, с которым он отказывается работать:

import { Component, } from '@angular/core';
import { NgClass } from '@angular/common';
import { ROUTER_DIRECTIVES } from '@angular/router';

import {MobileService} from '../';

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
})
export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(public ms: MobileService) {
    console.log(ms);
  }

}

Я получаю ошибку в консоли браузера:

ИСКЛЮЧЕНИЕ: Не удается разрешить все параметры для HeaderComponent: (?).

У меня есть сервис в функции начальной загрузки, поэтому у него есть провайдер. И я, кажется, могу вставить его в конструктор любого из моих других компонентов без проблем.

Ответ 1

Импортируйте его из файла, где он объявлен непосредственно, а не в бочке.

Я не знаю, что именно вызывает проблему, но я видел, как это упоминалось несколько раз (вероятно, какая-то циклическая зависимость).

Он также должен быть исправлен путем изменения порядка экспорта в стволе (не знаю деталей, но также упоминался)

Ответ 2

В дополнение к предыдущим приведенным ответам, похоже, эта ошибка также возникает, когда вашей инъекционной службе не хватает фактического декоратора @Injectable(). Поэтому перед тем, как вы отлаживаете элемент циклической зависимости и порядок импорта/экспорта, выполните простую проверку, действительно ли ваша служба имеет @Injectable().

Это относится к текущему Angular последнему, Angular 2.1.0.

Я открыл проблему по этому вопросу.

Ответ 3

Начиная с Angular 2.2.3 теперь есть функция утилиты forwardRef(), которая позволяет вам вводить поставщиков, которые еще не определены.

Не определено, я имею в виду, что карта инъекций зависимостей не знает идентификатора. Это то, что происходит во время круговых зависимостей. Вы можете иметь круговые зависимости в Angular, которые очень трудно распутать и посмотреть.

export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(@Inject(forwardRef(() => MobileService)) public ms: MobileService) {
    console.log(ms);
  }

}

Добавление @Inject(forwardRef(() => MobileService)) к параметру конструктора в исходном исходном коде вопроса устранит проблему.

Ссылки

Angular 2 Руководство: ForwardRef

Переслать ссылки в Angular 2

Ответ 4

НЕПРАВИЛЬНО # 1: Забывание декоратора:

//Uncaught Error: Can't resolve all parameters for MyFooService: (?).
export class MyFooService { ... }

НЕПРАВИЛЬНО # 2: Опуская символ "@" Символ:

//Uncaught Error: Can't resolve all parameters for MyFooService: (?).
Injectable()
export class MyFooService { ... }

НЕПРАВИЛЬНО # 3: Опускание "()" Символы:

//Uncaught Error: Can't resolve all parameters for TypeDecorator: (?).
@Injectable
export class MyFooService { ... }

НЕПРАВИЛЬНО # 4: Нижний регистр "i":

//Uncaught ReferenceError: injectable is not defined
@injectable
export class MyFooService { ... }

НЕПРАВИЛЬНО # 5: Вы забыли: import {Injectable} из '@angular/core';

//Uncaught ReferenceError: injectable is not defined
@injectable
export class MyFooService { ... }

ПРАВИЛЬНО:

@Injectable()
export class MyFooService { ... }

Ответ 5

Как уже было сказано, проблема вызвана экспортным упорядочением внутри ствола, вызванным круговыми зависимостями.

Более подробное объяснение здесь: fooobar.com/questions/32947/...

Ответ 6

Я также столкнулся с этим, вводя службу A в службу B и наоборот.

Я думаю, это хорошо, что это быстро не сработает, так как, вероятно, его все равно следует избегать. Если вы хотите, чтобы ваши услуги были более модульными и могли использоваться повторно, лучше избегать циклических ссылок в максимально возможной степени. Этот пост освещает подводные камни, связанные с этим.

Поэтому у меня есть следующие рекомендации:

  • Если вы чувствуете, что классы взаимодействуют слишком часто (я говорю о зависти к функциям), вы можете рассмотреть возможность объединения двух сервисов в один класс.
  • Если вышеперечисленное не работает для вас, рассмотрите возможность использования третьей службы (EventService), которую обе службы могут внедрить для обмена сообщениями.

Ответ 7

В интересах поисковиков; Я получил эту ошибку. Это был просто отсутствующий символ @.

т.е. Это вызывает ошибку Can't resolve all parameters for MyHttpService.

Injectable()
export class MyHttpService{
}

Добавление отсутствующего символа @ исправляет его.

@Injectable()
export class MyHttpService{
}

Ответ 8

В моем случае мне нужно было добавить import "core-js/es7/reflect"; в мое приложение, чтобы заставить @Injectable работать.

Ответ 9

Вы получаете эту ошибку, если у вас есть служба A, которая зависит от статического свойства/метода службы B и службы B зависит от сервиса A. Так что это своего рода циклическая зависимость, хотя это не так, поскольку свойство/метод статично. Вероятно, ошибка, возникающая в сочетании с AOT.

Ответ 10

В дополнение к отсутствующему декоратору @Injectable()

Отсутствует декодер @Injectable() в абстрактном классе, который не может разрешить все параметры для службы: (?) Декоратор должен присутствовать в MyService, а также в производном классе BaseService

//abstract class
@Injectable()
abstract class BaseService { ... }

//MyService    
@Injectable()
export class MyService extends BaseService {
.....
}

Ответ 11

В моем случае это произошло потому, что я не объявлял тип для параметра конструктора.

У меня было что-то вроде этого:

constructor(private URL, private http: Http) { }

а затем, изменив его на приведенный ниже код, решила мою проблему.

constructor(private URL : string, private http: Http) {}

Ответ 12

Другая возможность - не устанавливать для emitDecoratorMetadata значение true в tsconfig.json.

{
  "compilerOptions": {

     ...

    "emitDecoratorMetadata": true,

     ...

    }

}

Ответ 13

Удаление параметров из метода инъецируемого конструктора() разрешило его для моего случая.

Ответ 14

для меня это было просто отсутствие () в @Injectable. Proper - это @Injectable()

Ответ 15

В моем случае это было из-за плагина Augury, отключить его будет нормально. Альтернативный вариант есть, тоже работает.

все кредиты @Boboss74, он разместил ответ здесь: https://github.com/angular/angular/issues/23958

Ответ 16

Ну, для меня проблема была еще более раздражающей, я использовал сервис в сервисе и забыл добавить его как зависимость в appModule! Надеюсь, что это поможет кому-то сэкономить несколько часов, нарушающих приложение, только чтобы восстановить его снова.

Ответ 17

Вам нужно добавить массив поставщиков в @Component decorator или в модуль, в котором объявлен ваш компонент. Внутренний компонент можно сделать следующим образом:

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
  providers: [MobileService]
})

Ответ 18

В моем случае, передача неправильных параметров в конструктор генерирует эту ошибку, основная идея этой ошибки заключается в том, что вы неосознанно передали некоторые неправильные аргументы любой функции.

export class ProductComponent {
    productList: Array<Product>;

    constructor(productList:Product) { 
         // productList:Product this arg was causing error of unresolved parameters.
         this.productList = [];
    }
}

Я решил это, просто убрав этот аргумент.

Ответ 19

Для меня, я получил эту ошибку, когда я по ошибке отключил этот импорт в файле polyfills.ts, вы должны убедиться, что он импортирован, чтобы избежать этой ошибки.

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';

Ответ 20

В моем случае я пытался расширить NativeDateAdapter " NativeDateAdapter ", чтобы переопределить метод format(date: Date, displayFormat: Object) ".

В AngularMaterial-2 DatePicker.

Поэтому я забыл добавить @Injectable.

После того, как я добавлю это в мой класс "CustomDateAdapter":

@Injectable({
  providedIn: 'root'
})

Ошибка ушла.

Ответ 21

Я столкнулся с этой ошибкой, ошибочно указав имя службы, т.е. конструктор (private myService: MyService).

Для служб с ошибками я смог определить, какая из этих служб является проблемой (у меня было несколько перечисленных в конструкторе), просмотрев страницу в Chrome- > Console. Вы увидите как часть сообщения список параметров "parameter", показывая объект Object, Object Object,? (или что-то типа того). Обратите внимание, где "?" это и есть позиция службы, которая вызывает проблему.

Ответ 22

Хотя, возможно, упоминалось упорядочение экспортируемых классов из бочек, следующий сценарий также может дать тот же эффект.

Предположим, у вас есть классы A, B и C экспортированные из одного и того же файла, где A зависит от B и C:

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

@Injectable()
export class B {...}

@Injectable()
export class C {...}

Поскольку зависимые классы (т.е. в этом случае классы B и C) еще не известны Angular, (вероятно, во время выполнения во время процесса внедрения зависимостей Angular в класс A) возникает ошибка.

Решение

Решение состоит в том, чтобы объявить и экспортировать зависимые классы перед классом, в котором выполняется DI.

то есть в вышеприведенном случае класс A объявляется сразу после определения его зависимостей:

@Injectable()
export class B {...}

@Injectable()
export class C {...}

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

Ответ 23

В моем случае я экспортировал Class и Enum из одного и того же файла компонента:

mComponent.component.ts:

export class MyComponentClass{...}
export enum MyEnum{...}

Затем я пытался использовать MyEnum от потомка MyComponentClass. Это было причиной ошибки "Не удается разрешить все параметры".

Переместив MyEnum в отдельную папку из MyComponentClass, это решило мою проблему!

Как отметил Гюнтер Цохбауэр, это происходит из-за того, что услуга или компонент циклически зависимы.

Ответ 24

Если ваша служба определена в том же файле, что и компонент (который ее использует), а служба определена после компонента в файле, вы можете получить эту ошибку. Это связано с той же проблемой 'forwardRef', о которой упоминали другие. В настоящее время VSCode не очень хорошо показывает эту ошибку, и сборка успешно компилируется.

Запуск сборки с --aot может замаскировать эту проблему из-за того, как работает компилятор (вероятно, связанный с дрожанием дерева).

Решение. Убедитесь, что служба определена в другом файле или перед определением компонента. (Я не уверен, можно ли использовать forwardRef в этом случае, но это кажется неуклюжим).

Если у меня есть очень простой сервис, который очень сильно привязан к компоненту (вроде как модель представления) - например. ImageCarouselComponent, я могу назвать его ImageCarouselComponent.service.ts чтобы он не смешивался с другими моими службами.

Ответ 25

В моем случае это была круговая ссылка. У меня был MyService, вызывающий Myservice2, и MyService2, вызывающий MyService.

Нехорошо :(

Ответ 26

В моем случае причина была следующая:

  • мой инъекционный сервис А продлил еще один класс Б
  • У B был конструктор, который требовал аргумента
  • Я не определил ни одного конструктора в A

Как следствие, при попытке создать объект A конструктор по умолчанию потерпел неудачу. Я понятия не имею, почему это не было ошибкой компиляции.

Я исправил это, просто добавив конструктор в A, который правильно назвал конструктор B.

Ответ 27

При использовании импорта стволов - сначала сначала импортируйте инъекции, как правило.

Ответ 28

Это происходит при обращении к interface.

Изменение interface для class исправлено, работа с и без @Inject.

Ответ 29

Иногда это происходит, когда вы объявили Angular встроенный модуль (HttpClientModule, HttpErrorResponse и т.д.) в app.module.js. Я также столкнулся с той же проблемой, но теперь решил.

Ошибка, которую я сделал, это указать HttpClientModule в Провайдеры вместо Импорт Angular Module

Ответ 30

Для меня это было потому, что я перестал использовать флаг -aot, пытаясь ускорить время компиляции.

 ng serve -aot