2017-01-16 5 views
2

Допустим, у меня есть Угловое 2, которая строится следующим образом:Совместное использование Угловое 2 службы между нижестоящими компонентами, которые не разделяют один и тот же родительский компонент

enter image description here

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

Теперь скажите, что я хочу создать класс MyService, который будет использоваться для каждого вертикального столбца компонентов для детей. В частности, я хочу иметь возможность вводить MyService в компонент B и компоненты конструктора C, с угловым созданием двух экземпляров службы в целом (один для первого столбца дочерних компонентов и другой для второго столбца дочерних компонентов).

Один из способов сделать это, чтобы обернуть каждый столбец дочерних компонентов в промежуточном компоненте P, а затем объявить MyService в качестве поставщика в его @Component декоратора с использованием providers: [MyService]. Это гарантирует, что каждый экземпляр P (и, следовательно, все его дочерние компоненты, а) получат свой собственный экземпляр MyService:

enter image description here

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

Есть ли простой способ достичь этого в угловом 2? Благодаря!

ответ

1

Родительский компонент, в котором размещается инжектор, и MyService поставщик является правильным решением. Вот как работает Angular 2 DI. Даже при наличии услуги одиночки, MyServiceFactory, которые могут создавать MyService экземпляров классов, как бы это определить, что B и C должны получить общий MyService экземпляр, учитывая, что есть несколько B s и C s?

Родительский компонент предпочтительнее, если нет неразрешимых проблем с макетом. В противном случае это может быть директива с MyService поставщиком,

@Directive({ 
    selector: '[p]', 
    providers: [MyService] 
}) 
class P {} 

, что приводит к прозрачной компоновке с

<ng-container p> 
    <b></b> 
    <c></c> 
</ng-container> 
<ng-container p> 
    <b></b> 
    <c></c> 
</ng-container> 
+0

Спасибо! Я не знал о 'ng-container' ... попробуем это! –

+0

На второй мысли ... Я до сих пор не вижу, как можно использовать 'ng-container' в этом случае. Например, что, если я хочу поделиться экземпляром службы между верхним левым компонентом 'B' и нижним правым компонентом' C'? Перетасовка шаблона шаблона для того, чтобы заставить инъекцию зависимостей работать так, как я хочу, это не звучит как очень гибкое решение для меня (то есть, если мне нужно изменить макет шаблона значительно позже?). Можно ли каким-то образом указать эти группировки, не требуя, чтобы они принадлежали к одному узлу DOM и/или 'ng-container'? –

+0

Угловой не «гибкий», он самоуверенный. Если вы знаете, как это работает достаточно хорошо, вы можете эффективно разработать приложение и знать, чего ожидать. До тех пор, пока не возникнут проблемы с дизайном, они являются частью кривой обучения. – estus

0

А что насчет статического EventEmitter оба компонента подписаться?

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

//the "commands dispatcher" class : 

import { EventEmitter } from '@angular/core'; 

export class CommandsDispatcherService { 
    private static store: { [channel: string]: EventEmitter<any> } = {}; 

    static get(channel: string): EventEmitter<any> { 
    if (!this.store[channel]) { 
     this.store[channel] = new EventEmitter(); 
    } 
    return this.store[channel]; 
    } 
} 

Компоненты & B (без каких-либо иерархических отношений) просто импортировать класс (не провайдера), подписаться на него по инициализации и использовать метод GET для общения друг с другом на своем собственном канале. Я нашел это довольно круто.