Angular 5. Почему провайдеру нужен компонент. InjectorError - PullRequest
0 голосов
/ 29 апреля 2018

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

код

import { Injectable } from '@angular/core';
import { AppComponent } from '../app.component';
import { FilmComponent } from '../film/film.component';
import { UserService } from './user.service';


@Injectable()
export class UpdateDataService {
  constructor(private app: AppComponent, private film: FilmComponent, private user: UserService) {}

  updateWhenAuthorized() {
    console.log('user_authorized');
    this.app.current_user_avatar = this.user.getUSer().Avatar;
    this.app.user_authorized = true;
    this.app.show_favorite = true;
    this.app.IsAutentification = false;
    this.film.current_user_avatar = this.user.getUSer().Avatar;
    this.film.showElseNeedLoginForCommentBlock = false;
  }

  updateWhenLogout() {
    console.log('user_logout');
    this.app.user_authorized = false;
    this.app.show_favorite = false;
    this.film.showElseNeedLoginForCommentBlock = true;
  }
}

Но когда я пытаюсь войти в систему, я получаю сообщение об ошибке

NullInjectorError: No provider for FilmComponent!

Вот ссылка на github, там вы можете помомреть весь проект, который был бы понятнее Я не понимаю. Я сделал тот же FilmComponent в сервисе через конструктор класса

https://github.com/Ascolon/electron-angular

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Пара проблем здесь:

Во-первых:

Вы вводите компоненты в службы, что не имеет смысла. Как я понимаю из вашего кода, несколько компонентов должны быть обновлены из сервиса. Так почему бы не использовать что-то вроде Subjects или BehaviorSubject? Ваша служба будет выдавать новые значения с subject.next, и компоненты будут подписываться на эти события. Смотрите краткий пример здесь .

Второе:

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

Я заглянул в репозиторий Github. связал и увидел, что вы предоставляете услугу каждому компоненту в отдельности, что означает, что каждый компонент получит отдельный экземпляр службы. Это может вызвать у вас проблемы. Вы, вероятно, хотите добавить сервисы в массив провайдера модуля. Таким образом, все компоненты этого модуля будут получать одноэлементный экземпляр этой службы при внедрении. Более подробное объяснение см. На угловом сайте .

0 голосов
/ 29 апреля 2018

Это не так, как в Angular (или Typescript).

constructor() для внедрения зависимостей. UpdateDataService - это Singleton, внедренный в корневой компонент приложения. Когда вы вводите его, ** FilmComponent **, вероятно, не инициализируется.

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

В эксплуатации:

  surUsrAvtr = new BehaviourSubject<any>();
  showElse = new BehaviourSubject<any>();

  updateWhenAuthorized() {
    console.log('user_authorized');
    this.app.current_user_avatar = this.user.getUSer().Avatar;
    this.app.user_authorized = true;
    this.app.show_favorite = true;
    this.app.IsAutentification = false;
    this.surUsrAvtr.next(this.user.getUSer().Avatar);
    this.showElse.next(false);
  }

  updateWhenLogout() {
    console.log('user_logout');
    this.app.user_authorized = false;
    this.app.show_favorite = false;
    this.showElse.next(true);
  }

А в компоненте подписывайтесь на такие:

export class FilmComponent implements OnInit {

  urrent_user_avatar: any;
  showElseNeedLoginForCommentBlock: any;

  constructor(private upDataService: UpdateDataService) {}

  ngOnInit() {
    this.upDataService.surUsrAvtr.subscribe(_ => this.urrent_user_avatar = _);
    this.upDataService.showElse.subscribe(_ => this.showElseNeedLoginForCommentBlock = _);
  }
}

То же самое относится и к AppComponent

...