2016-04-18 2 views
2

Я проходил учебник «Герои» на официальной странице «Угловая 2», и когда я пришел на маршрутизацию, несколько вещей не имели смысла. Речь идет о провайдерах.Угловая 2 - как провайдеры действительно работают?

Данная деталь представлена ​​ниже. Мой главный компонент выглядит следующим образом:

/* app.components */ 
import {Component} from 'angular2/core'; 
import {HeroesComponent} from './heroes.component'; 
import {HeroService} from './hero.service'; 

@Component({ 
    selector: 'my-app', 
    template: ` 
     <h1>{{title}}</h1> 
     <my-heroes></my-heroes> 
    ` 
    directives: [HeroesComponent], 
    providers: [HeroService] 

}) 
export class AppComponent { 
    title = 'Tour of Heroes'; 
    constructor(private _heroService: HeroService) {} 
} 

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

/* heroes.component */ 
import {Component} from 'angular2/core'; 
import {Hero} from './hero'; 
import {HeroDetailComponent} from './hero-detail.component'; 
import {HeroService} from './hero.service'; 
import {OnInit} from 'angular2/core'; 

@Component({ 
    selector: 'my-heroes', 
    directives: [HeroDetailComponent], 
    template: ` 
     <h2>My Heroes</h2> 
     <ul class="heroes"> 
      <li *ngFor="#hero of heroes" [class.selected] = "hero === selectedHero" (click)="onSelect(hero)"> 
       <span class="badge"> {{hero.id}} </span> {{hero.name}} 
      </li> 
     </ul> 
     <my-hero-detail [hero]="selectedHero"></my-hero-detail> 
     ` 
}) 
export class HeroesComponent implements OnInit { 
    heroes: Hero[]; 
    selectedHero: Hero; 
    ngOnInit() { 
     this.getHeroes(); 
    } 
    constructor(private _heroService: HeroService) { } 

    getHeroes() { 
     this._heroService.getHeroes().then(heroes => this.heroes = heroes); 
    } 

    onSelect(hero: Hero) { 
     this.selectedHero = hero; 
    } 

} 

OK, поэтому мой вопрос: для того, чтобы это работало, мне нужно импортировать import {HeroService} from './hero.service'; в обоих файлах , Однако providers: [HeroService] является лишь частью @Componentapp.components. Мне не нужно писать этот фрагмент кода в heroes.component. Как heroes.component знает, какой поставщик выбрать? Наследуется ли она от app.components? И если да, то зачем мне писать это в обоих файлах: import {HeroService} from './hero.service';? Почему не только в app.components? Оба класса также имеют одинаковые constructor. Я не знаю, что здесь происходит, поэтому заранее спасибо за любое объяснение.

ответ

0

Инъекторы являются иерархическими. В bootstrap() корневой провайдер инициализируется, затем для каждого компонента создается еще один дочерний инжектор, который приводит к структуре, которая имитирует ваши компоненты в DOM.

Когда Угловой экземпляр класса (сервис, компонент, труба, ...), он запрашивает экземпляр DI и DI, который также пытается разрешить параметры конструктора. Это рекурсивно выполняется до тех пор, пока не потребуются дальнейшие зависимости для разрешения, затем возвращается экземпляр.

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

Для получения более подробной информации см https://angular.io/docs/ts/latest/api/core/Directive-decorator.html

0

Это связано с «иерархические инжекторов» особенность Angular2. Эти форсунки связаны с компонентами и следуют одному и тому же дереву.

Инжектор дочернего компонента является вспомогательным инжектором родительского компонента. Если поставщик не найден в текущий инжектор, то он будет искать в родитель один ...

Смотрите этот вопрос для более подробной информации:

0

Да, это унаследовано, а инжекторы являются иерархическими. Проверьте этот блог post и официальный documentation.

0

После изучения некоторых документов Angular-2 Я поделился своими знаниями о dependency-injection and providers, которые могут кому-то помочь.

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

Зависимости являются одноточечными в пределах объема инжектора. В нашем примере один HeroService экземпляр совместно используется среди AppComponent и его детей HeroComponent.

В вашем примере AppComponent является корневым компонентом области объектов Heroes. Он управляет всеми дочерними компонентами этой области. Yur HeroService может предоставить метод getHeroes, который возвращает данные heros, но ни один из его потребителей не должен это знать.

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

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

bootstrap(AppComponent, 
     [HeroService]); // DISCOURAGED (but works) 

Инжектор теперь знает о наших HeroService. Экземпляр нашего HeroService будет доступен для инъекций по всему нашему приложению.

Предпочтительный подход заключается в регистрации поставщиков приложений в компонентах приложения. Поскольку HeroService используется в области объектов Heroes - и нигде больше - идеальное место для регистрации, оно находится на верхнем уровне HeroesComponent.

регистрирующие провайдеров в компоненте

providers:[HeroService], // in your app.component that registers the HeroService 

Посмотрите внимательно на providers части @Component метаданных.

Экземпляр HeroService теперь доступен для инъекций в этом AppComponent и всех его дочерних компонентов.

Самолет AppComponent не нуждается в службе HeroService. Но его ребенок HeroComponent делает.

Фокус на конструктор

Добавление параметра в конструктор.

constructor(private _heroService: HeroService) { 
    this._heroService.getHeroes().then(heroes => this.heroes = heroes); // or you can use in OnInit 
} 

N.B: мая нет необходимости использовать constructor в вашем appComponent

Мы пишем в машинописном и последовавшее имя параметра с типом аннотациями, :HeroService.Класс также украшен декоратором @Component.

Когда машинописи компилятор обрабатывает этот класс, он видит @Component декоратора и добавляет метаданные класса в генерируемый код JavaScript. Внутри этих метаданных скрывается информация, что связывает параметр heroService с классом HeroService.

Вот как Угловая инжектор знает, чтобы ввести экземпляр HeroService, когда он создает новый HeroComponent.

Подробнее для инъекции зависимостей можно увидеть this link

и иерархической-зависимости инъекции можно увидеть this link

Смежные вопросы