Правильный способ передачи определенного экземпляра службы в модальное окно с помощью ngx-bootstrap

Я пытаюсь передать конкретный экземпляр службы компонентам, находящимся внутри модального окна ngx-bootstrap.

Однако, поскольку модальное окно не является дочерним по отношению к компоненту, запускающему модальное окно, оно не может разрешить зависимость службы, если я попытаюсь его внедрить.

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

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

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

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

Пример Stackblitz (передача службы в виде данных, а затем в качестве ввода):

https://stackblitz.com/edit/ngx-modal-25zz6k?file=src/app/app.component.ts.

Главный компонент:

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [AppService],
})
export class AppComponent {

  modalRef: BsModalRef;
  constructor(private modalService: BsModalService, private appService: AppService, private injector: Injector) {}

  openModal() {
    this.appService.increment();
    this.modalRef = this.modalService.show(SomeComponent,  {
      initialState: {
        title: 'Modal title',
        appService: this.appService,
      },
    });
  }
}

Модальный компонент:

export class SomeComponent implements OnInit {
  appService: AppService;
  title;
  constructor(
    public modalRef: BsModalRef,
  ) {
  }

  ngOnInit() {

  }

}

Потомок SomeComponent:

export class ChildComponent implements OnInit {
  constructor(
    public modalRef: BsModalRef,
  ) { }

  @Input() appService: AppService;

  count: number = 0;

  ngOnInit() {
    this.count = this.appService.num;
  }
}

В идеале я бы хотел, чтобы он работал аналогично тому, как это делает ng-bootstrap, где я могу передать пользовательский инжектор в модальное окно, подобное:

this.modal.open(SomeComponent, {
  injector: Injector.create([{
    provide: AppService, useValue: this.appService
  }], this.injector)
}) 

Возможность добавить AppService к инжектору SomeComponent тоже была бы в порядке, но из того, что я пробовал, единственными способами для инъекции было бы выполнить его во время создания компонента, а AppService не определен до тех пор, пока не будет запущен ngOnInit в SomeComponent.

Я чувствую, что что-то вроде этого также будет работать в SomeComponent:

constructor(@Inject(forwardRef(() => returnObservableForAppService)) appServiceObsv: Observable<AppService>) { }

Но внедрение Observable вместо фактического сервиса выглядит примерно так же, как простая передача его в качестве входных данных.


person Asguard    schedule 23.09.2019    source источник


Ответы (1)


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

const injector = Injector.create({
  providers: [
    { provide: AppService, deps: [] },
  ]
});

export const appService = injector.get(AppService);

Затем в необходимых компонентах импортируйте appService и используйте его:

import { appService } from '....';

// ...

openModal() {
  appService.increment();
  this.modalRef = this.modalService.show(SomeComponent, {
    initialState: {
      title: 'Modal title'
    },
  });
}

импортировать то же самое для ChildComponent и ...

ngOnInit() {
  this.count = appService.num;
}

ваш разветвленный STACKBLITZ

person AJT82    schedule 24.09.2019
comment
Разве этот подход не будет делать то же самое, что и providedIn: 'root' в службе? stackblitz.com/edit/ngx-modal- ciu2xh? file = src / app / - person Asguard; 24.09.2019
comment
Может я неправильно понял. Я думал, вы имели в виду, что хотите, чтобы отдельный экземпляр этой службы использовался только в этих компонентах. Это не то, что вам нужно? - person AJT82; 24.09.2019
comment
Ну, если вы, например, хотите создать новый экземпляр при входе в основной компонент ... тогда всегда создавайте новый экземпляр службы там, когда компонент создается с использованием Injector? Пытаюсь понять здесь вариант использования, так что, возможно, я совершенно не понимаю: D - person AJT82; 24.09.2019