6

I want the child component to access the shared service take the data and after injecting the child component to main component. I want the data of the sharedservice(rootscope) to directly put the data in mainComponents HTML, like here.

mainComponent.ts

import { Component } from '@angular/core';
import {ChildComponent} from './child';
import {AppServiceService} from './app-service.service';

@Component({
  moduleId: module.id,

  selector: 'rootscope-app',

  templateUrl: 'rootscope.component.html',

  styleUrls: ['rootscope.component.css'],

  directives:[ChildComponent]

})

export class RootscopeAppComponent {

  title = 'rootscope works!';

  display:any;

  constructor(appServiceService:AppServiceService){  

    this.display=appServiceService.getter();

  }
}

sharedService.ts

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


@Injectable()

export class AppServiceService {

  ser = "hello i am from service";

  public data: any;

  constructor() {

  }

  settter(data: any) {

    this.data = data;

  }

  getter() {

    return this.data;
  }
}

childComponent of mainComponent

import { Component, OnInit } from '@angular/core';

import {AppServiceService} from '../app-service.service'

@Component({
  moduleId: module.id,

  selector: 'app-child',

  templateUrl: 'child.component.html',

  styleUrls: ['child.component.css']

})

export class ChildComponent implements OnInit {

  dispaly: string;

  constructor(appServiceService: AppServiceService) {

    this.dispaly = "Child component binding...";

    appServiceService.settter(this.dispaly);

  }

  ngOnInit() {}
}
Mel
  • 5,837
  • 10
  • 37
  • 42
Prashobh K V
  • 161
  • 1
  • 2
  • 11
  • 2
    `$rootScope` and `$scope` both are not in Angular2. You can think of `shareService` and inject it into `boostrap` function. This way you will be able to share you data throughout application(HTML as well). – micronyks Jun 04 '16 at 06:40
  • but then also i can't access the data which is there in shareService directly in html without using the that html's component – Prashobh K V Jun 04 '16 at 06:53
  • you can use shareservice data into HTML directly. Just inject it into your controller that's it. – micronyks Jun 04 '16 at 06:54
  • Possible duplicate of [Angular 2 - What is equivalent to Root Scope?](http://stackoverflow.com/questions/35985009/angular-2-what-is-equivalent-to-root-scope) – Mark Rajcok Jun 04 '16 at 16:13
  • it is same thing but using shared service i was not able to access the data in HTML . – Prashobh K V Jun 06 '16 at 04:47
  • This only works if the constructor in `ChildComponent` is executed before the constructor of `RootscopeAppComponent` which I wouldn't rely upon. I think it's better to use a `BehaviorSubject` and `subscribe()` (like shown for example in http://stackoverflow.com/questions/37429824/receiving-multiple-instances-of-data-from-behavior-subject-every-time-component/37430037#37430037) – Günter Zöchbauer Jun 06 '16 at 06:42

3 Answers3

4

$rootScope and $scope both are not available in Angular2. You can think to use service (shareService) and inject it into boostrap function. This way you will be able to share data throughout application(HTML as well).

Look at here. http://plnkr.co/edit/7A21ofKNdi0uvbMgLUDZ?p=preview

bootstrap(App, [sharedService]);

sharedService

import {Injectable} from 'angular2/core'

@Injectable()
export class sharedService {
    name="micronyks";
} 

Component

@Component({
  selector: 'thecontent',
    template: `
    <h1>Component II - {{ss.name}}   </h1>
        `
})
export class TheContent {
  constructor(private ss: sharedService) {
    console.log("content started");
  }
}
micronyks
  • 54,797
  • 15
  • 112
  • 146
  • i want to access the shared service directly in html like we had angular as mentioned above.@Component({ selector: 'thecontent', template: `

    Component II - {{sharedservice.name}}

    ` })// i don't want to create an object export class TheContent { constructor(private ss: sharedService) { console.log("content started"); }
    – Prashobh K V Jun 06 '16 at 06:57
  • @micronyks when I change a data in the service, it will be reflected in the other pages? – Kamuran Sönecek Oct 06 '17 at 08:37
  • 1
    @KamuranSönecek yes it will reflect in other pages but you have to make sure that all pages share the single instance of the service else it will not work. – micronyks Oct 06 '17 at 14:07
  • $rootScope in angularJS will be watched for value change. But the example you have give won't work if we want to keep the data updated in injected component. – Paul Richard Feb 11 '19 at 11:45
  • @PaulRichard for that you can use `RXJS` library and its `observables`. eg. `BehaviorSubject` – micronyks Feb 12 '19 at 08:49
  • @micronyks yes I agree, please update your answer with the Observable implementation. Thank you. – Paul Richard Feb 12 '19 at 12:35
1

Given the desired output is that we want to use shared values inside any template, then using a service is not an answer.

The solution is making a base class to all components, where everything we need globally resides.

create a class, name it BaseComponent

export class BaseComponent{

   constructor(){}

   public someMethod(): string{
     return "some string";
   }

   //and whatever methods you need, a method can call services and return data from it

}

and make every component extends it

export class TestPage extends BaseComponent {

and inside its HTML template

<span> {{someMethod()}} </span>

or alternatively if you want a change in the view (template) to be fired from a service function call, you can place a callback in the service and assign it from the component so it will be fired whenever the service function called, take this case as an example

In my case I wanted to show a message that can be fired from any component, so I placed it in the app.component.html which survives along the app lifetime

    <div class="col-lg-12">
        <div [hidden]="!msg" (click)="msg=''" class="alert alert-info" role="alert">
            {{msg}}
        </div>
    </div>

inside the app.component.ts

constructor(private main: MainService){}

msg: string = "";
ngOnInit(): void {
    this.main.showMsg = (msg)=>{this.msg = msg;}
}

the MainService is the service that contains the callback, as you see below

//main.service.ts
public showMsg:(msg: string)=>void;

now from any component, with the main service registered in the constructor, you can show the message as follows

if(this.main.showMsg){
     this.main.showMsg("the message text");
}
Mohamed Ali
  • 3,717
  • 1
  • 33
  • 39
  • 1
    You cannot really share some data (think static data) when using base component and inheritance like this, but yes the functions can be used. This is like a base class and concept of inheritance is meant for different purpose – ANewGuyInTown Nov 21 '17 at 00:51
0

it is possible by using angular BehaviorSubject and asObservable

Check below example code

Service file

@Injectable()
export class commonService {
    private data = new BehaviorSubject('');
    currentData = this.data.asObservable()

    constructor() { }

    updateMessage(item: any) {
        this.data.next(item);
    }

}

Component

Set the data from any component

 constructor(private _data: commonService) { }
 shareData() {
      this.currentValue = this.queryTerm;
      this._data.updateMessage(this.currentValue);
  }

Listen from any component

constructor(private _data: commonService) { }
ngOnInit() {
        this._data.currentData.subscribe(currentData => this.currentValue = currentData)
    }

You can communicate between any component using this way.

Machavity
  • 30,841
  • 27
  • 92
  • 100
Prashobh
  • 9,216
  • 15
  • 61
  • 91