Angular: проблема с синглтон-сервисом и матом - PullRequest
1 голос
/ 10 января 2020

Я пытаюсь использовать мой синглтон-сервис в Mat Dialog, но пока не смог этого сделать. Новый экземпляр службы создается при первом открытии диалогового окна, и я получаю неопределенный список userList по адресу user-options-provider.service.ts . Единственная полезная информация, которую я мог получить в Интернете об этом, - то, что Матовый диалог создан вне области для этой услуги. Так есть ли способ использовать мой одноэлементный сервис в компоненте Mat Dialog?

user-options-provider.service.ts

@Injectable({
  providedIn: 'root'
})
export class UserOptionsProviderService {

  private userList: Array<User>;

  private userListObs = new BehaviorSubject<Array<User>>(this.userList);

  constructor(private boardsProviderService: BoardsProviderService) {  }

  setUserList(id: string): void {
    this.userList = this.boardsProviderService.getBoard(id).userList;
    this.userListObs.next(this.userList);
  }

  getUserListObs(): Observable<Array<User>> {
    return this.userListObs.asObservable();
  }
}

user- options.component.ts

@Component({
  selector: 'app-user-options',
  templateUrl: './user-options.component.html',
  styleUrls: ['./user-options.component.css']
})
export class UserOptionsComponent implements OnInit {

  userList: Array<User>;

  constructor(public dialog: MatDialog,
              public dialogRef: MatDialogRef<UserOptionsComponent>,
              private userOptionsProviderService: UserOptionsProviderService) {

    this.userOptionsProviderService.getUserListObs().subscribe((users: Array<User>) => {
      this.userList = users;
    });

  }

  ngOnInit() { }

вызывается и предоставляется в board.component.ts

  onClickUserOptions(boardId: string): void {
    this.dialog.open(UserOptionsComponent, {
      data: {boardId}
    });
  }

Ответы [ 2 ]

1 голос
/ 10 января 2020

Ссылка на работающий StackBlitz LINK

@Injectable({
  providedIn: 'root'
})
export class UserOptionsProviderService {

  // private userList: Array<User>; is undefined.
  // private userList: Array<User> = []; is a blank array.
  // Below is the correction.
  private userList: Array<User> = [];

  // new BehaviorSubject<Array<User>>(this.userList) is then 
  // new BehaviorSubject<Array<User>>(undefined)
  // you want to have this.userList be and []
  // new BehaviorSubject<Array<User>>([])
  private userListObs = new BehaviorSubject<Array<User>>(this.userList);

  constructor(private boardsProviderService: BoardsProviderService) {  }

  setUserList(id: string): void {
    this.userList = this.boardsProviderService.getBoard(id).userList;
    this.userListObs.next(this.userList);
  }

  getUserListObs(): Observable<Array<User>> {
    return this.userListObs.asObservable();
  }
}

Одна проблема за раз. Теперь в вашем компоненте сделайте это ...

@Component({
  selector: 'app-user-options',
  templateUrl: './user-options.component.html',
  styleUrls: ['./user-options.component.css']
})
export class UserOptionsComponent implements OnInit {

  userList: Array<User>;

  constructor(public dialog: MatDialog,
              public dialogRef: MatDialogRef<UserOptionsComponent>,
              private userOptionsProviderService: UserOptionsProviderService) {}

  ngOnInit() {
    this.userOptionsProviderService.getUserListObs().subscribe((users: Array<User>) => {
      this.userList = users;
    });
}

И вам все еще нужно вызвать serv cie .setUserList (id) для установки массива. Где вы планируете это делать? Либо в конструкторе службы, либо в компоненте. Где ты это сделаешь? Это метод, который устанавливает массив для фактического массива пользователей.

Вы также можете сделать это на основе вашего кода ...

  // In the board.component.ts file
  // You need to call setUserList() before you create the dialog
  // because when you create the dialog it pulls the subscription,
  // which in the initial state is a blank [];
  // You call the service, which loads the array, and by the time
  // the dialog loads it should be in the subscription.
  // Do this first to see that it works, then I'll send a stack blitz 
  // showing another way. In your case, the dialog is tied to the service
  // I think maybe you could give it a little more freedom.

  onClickUserOptions(boardId: string): void {
    this.UserOptionsProviderService.setUserList(boardId);
    this.dialog.open(UserOptionsComponent);
  }
0 голосов
/ 11 января 2020

Передача услуги сработала.

board.component.ts

  onClickUserOptions(): void {
    const s = this.userOptionsProviderService;
    this.dialog.open(UserOptionsComponent, {
      data: {s}
    });
  }

user-options.component.ts

export class UserOptionsComponent implements OnInit {

  s = this.data.s;
  userList: Array<User>;

  constructor(public dialog: MatDialog,
              public dialogRef: MatDialogRef<UserOptionsComponent>,
              @Inject(MAT_DIALOG_DATA) public data: any) {  }

  ngOnInit() {
    this.s.getUserListObs().subscribe((users: Array<User>) => {
      this.userList = users;
    });
  }
}

Большое спасибо:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...