Провайдеры Angular2 в bootstrap vs @component

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

bootstrap(
  App,
  [disableDeprecatedForms(), provideForms()]]
)

или в вашем корневом компоненте следующим образом:

@Component({
  selector: 'my-app',
  providers: [disableDeprecatedForms(), provideForms()],
  ...
)

Тем не менее, я создал подключаемый модуль проверки формы, для которого требуются провайдеры ProvideForms, и эта директива работает только в том случае, если параметры начальной загрузки. Я создал планк, чтобы проиллюстрировать проблему: валидатор работает, если я добавляю providerForms () к вызову начальной загрузки. Как только я закомментирую providerForms() из вызова начальной загрузки, валидатор больше не работает. Я предположил, что определения providerForms в компоненте достаточно. Любое объяснение?


person schacki    schedule 31.07.2016    source источник
comment
Компилятор среды выполнения создается до того, как вы внедряете поставщиков в AppComponent. Таким образом, компилятор использует старые классы форм в AppComponent.template.js. Метод useFactory в провайдерах AppComponent срабатывает только тогда, когда вы вставляете токен в конструктор. plnkr.co/edit/Ed8ao38phPNsYeHMorcg?p=preview   -  person yurzui    schedule 01.08.2016


Ответы (1)


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

Предоставление в bootstrap(...) и @Component(...) корневого компонента не эквивалентно, но это различие не относится ко всему внутри корневого компонента или одного из его дочерних элементов или других потомков. bootstrap() на один уровень выше корневого компонента.

Руководство по стилю Angular2 также предлагает предпочесть корневой компонент bootstrap(), потому что начальная загрузка должна быть зарезервирована для системных вещей.

Формы и маршрутизатор должны быть созданы до того, как будет создан первый компонент (например, в ранних версиях маршрутизатора V3 была ошибка, когда корневой компонент должен был вводить Router или содержать routerLink, иначе маршрутизатор не запускался) .

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

person Günter Zöchbauer    schedule 01.08.2016
comment
У вас есть идея, какая часть этих провайдеров отвечает за такое поведение? На что следует обращать внимание при выяснении, имеет ли провайдер право на инжектор без полномочий root или нет? Я надеялся, что мы оставили дискриминацию config/run в A1, но все выглядит так же. - person Estus Flask; 01.08.2016
comment
Не уверен, что вы имеете в виду под какой частью. Я знаю только из упоминаний в проблемах Angular2 GitHub, что provideRouter() нужно использовать в bootstrap() вместо корневых компонентов. Я не удивлен, что disableDeprecatedForms() и provideForms() требуют одного и того же, но я не знаю подробностей, почему именно. - person Günter Zöchbauer; 01.08.2016
comment
Можете ли вы предоставить ссылку на упомянутые проблемы github? - person schacki; 01.08.2016
comment
Спасибо за ссылку. Было бы неплохо узнать, каковы точные условия, которые могут заставить провайдера использоваться только в bootstrap. Я предполагаю, что это APP_INITIALIZER в случае маршрутизатора. Не уверен, что насчет форм... может быть, CompilerConfig? - person Estus Flask; 01.08.2016
comment
Есть ли конкретная причина, по которой это важно для вас? Меня это не слишком беспокоит, потому что я все равно ожидаю больших изменений в этой области с введением модулей в следующем выпуске. - person Günter Zöchbauer; 01.08.2016