2016-02-08 6 views
20

У меня есть объект, который я хочу разделить между моими компонентами в приложении Angular2.Angular2 - Обмен данными между компонентами с использованием служб

Вот источник первого компонента:

/* app.component.ts */ 

// ...imports 
import {ConfigService} from './config.service'; 

@Component({ 
    selector: 'my-app', 
    templateUrl: 'app/templates/app.html', 
    directives: [Grid], 
    providers: [ConfigService] 
}) 
export class AppComponent { 
    public size: number; 
    public square: number; 

    constructor(_configService: ConfigService) { 
     this.size = 16; 
     this.square = Math.sqrt(this.size); 

     // Here I call the service to put my data 
     _configService.setOption('size', this.size); 
     _configService.setOption('square', this.square); 
    } 
} 

и второй компонент:

/* grid.component.ts */ 

// ...imports 
import {ConfigService} from './config.service'; 

@Component({ 
    selector: 'grid', 
    templateUrl: 'app/templates/grid.html', 
    providers: [ConfigService] 
}) 
export class Grid { 
    public config; 
    public header = []; 

    constructor(_configService: ConfigService) { 
     // issue is here, the _configService.getConfig() get an empty object 
     // but I had filled it just before 
     this.config = _configService.getConfig(); 
    } 
    } 

и, наконец, мой маленький сервис, ConfigService:

/* config.service.ts */ 

import {Injectable} from 'angular2/core'; 

@Injectable() 
export class ConfigService { 

    private config = {}; 

    setOption(option, value) { 
     this.config[option] = value; 
    } 

    getConfig() { 
     return this.config; 
    } 
} 

Мои данные не разделяются, в grid.component.ts строка _configService.getConfig() возвращает пустой объект, bu t он заполняется непосредственно в app.component.ts.

Я читал документы и руководства, ничего не работало.

Что мне не хватает?

Благодаря

решаемые

Мой вопрос заключается в том, что я инъекционного мой ConfigService дважды. В бутстрапе приложения и в файле, где я его использую.

Я удалил настройку providers и ее работу!

+0

В качестве примечания стороны рассмотрите возможность перемещения вызовов службы из конструктора. – Stanislasdrg

+0

http://www.angulartutorial.net/2017/09/angular-share-data-between-components.html – Prashobh

ответ

22

Вы определяете его в своих двух компонентах. Таким образом, услуга не используется. У вас есть один экземпляр для компонента AppComponent, а другой - для компонента Grid.

@Component({ 
    selector: 'my-app', 
    templateUrl: 'app/templates/app.html', 
    directives: [Grid], 
    providers: [ConfigService] 
}) 
export class AppComponent { 
    (...) 
} 

Быстрое решение заключается в удалении атрибута providers в компоненте сетки ... Таким образом, экземпляр службы будет разделяемое AppComponent и его детей компонентов.

Другим решением является регистрация соответствующего провайдера в пределах функции bootstrap. В этом случае экземпляр будет совместно использоваться всем приложением.

bootstrap(AppComponent, [ ConfigService ]); 

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

+0

ОК, на самом деле у меня есть ... В бутстрапе и в провайдерах в каждом файле я хочу. Это может быть моей проблемой. Я тестирую его как можно скорее и расскажу вам, если это была проблема. – keversc

+0

Да, но вам это не нужно. Когда вы настраиваете поставщиков, объем связанного экземпляра будет элементом и его вспомогательными элементами. Определение снова воссоздает новый экземпляр. Например, если вы определяете своего провайдера в бутстрапе, а один в компоненте, у вас будет два экземпляра службы: один на уровне приложения и один на уровне компонента. –

+0

Если вы определяете только на уровне приложения, все компоненты могут использовать этот экземпляр путем инъекции зависимостей. Это связано с тем, что инжектором компонента является вспомогательный инжектор или прикладной. Они используют прототипное наследование. Ребенок может видеть элементы в родительском –

4

Не добавляйте ConfigService к providers вашего компонента. Это приводит к появлению новых экземпляров для каждого компонента. Добавьте его к providers общего родительского компонента. Если вы добавите его в свой корневой компонент или bootstrap(App, [ConfigService]), ваше приложение будет иметь один экземпляр.

+0

Хорошо спасибо, я посмотрю на это, пока у меня есть ConfigService как в начальной загрузке, так и в файле, это может быть моей проблемой. Я пробую это как можно скорее – keversc

5

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

бутстрап (AppComponent);

@NgModule({ 
    declarations: [ 
     .... 
    ], 
    imports: [ 
     ....  
    ], 
    providers: [ 
     ConfigService, 
.... 
Смежные вопросы